none
Eine Klasse in zwei unterschiedlichen Namespaces RRS feed

  • Frage

  • Hallo,

    ich habe 2 Assemblies Assembly1 und Assembly2, welche jeweils im GAC liegen.

    Die Klasse Connection im Namesprace MyNamespace existiert in beiden Assemblies.

    Wie kann ich definieren, welche Assembly ich nutzen möchte, wenn ich die Klasse MyNamespace.Connection in meinem PowerShell-Code nutze.

    Danke im Voraus und viele Grüße

    Donnerstag, 13. November 2014 12:35

Antworten

  • Ich glaube du bringst einfach die Begriffe Assembly, Namespace und Klasse durcheinander.
    Eine Assembly ist eine .dll die Klassen zu Verfügung stellt.
    Jede Klasse befindet sich in einem Namespace.

    Ein Namespace kann aus mehreren .dlls (Assemblies) bestehen.

    Der Namespace ist eine Pfad angabe zu der Klasse  damit Sie EINDEUTIG angesprochen werden kann.
    Eine Klasse kann nicht doppelt in einem Namespace sein. Der Namespace-Pfad identifiziert die Klasse IMMER eindeutig!

    Die Assemblies sind da völlig Egal, weil die Klasse IMMER über den Namespace angesprochen werden kann!

    In meinem Beispiel oben ist der FullName der Volle Pfad zu Klasse = der Namespace.

    Jetzt kommt es nur noch darauf an, ob du einen Statischen Member der klasse ansprechen willst, oder ob du ein Objekt von der Klasse benutzen möchtest.

    # Methode GetCultureInfo() ist ein statischer Member der Klasse System.Globalization.CultureInfo
    # Statische Member werden über den doppelten Doppelpunkt direkt aus der Klasse heraus angesprochen
    # deutsche Kultur Informationen abrufen. Mit angabe des Namespaces 
    [System.Globalization.CultureInfo]::GetCultureInfo('de-DE') | Select-Object *
    
    
    # Ein Objekt von einer Klasse wir mithilfe des Cmdlets New-Object erzeugt:
    # Ein neues KulturInfo Objekt erzeugen. Mit angabe des Namespaces
    $CultureInfo = New-Object -TypeName System.Globalization.CultureInfo -ArgumentList 'en-US'
    # anzeigen des Inhaltes von dem Objekt
    $CultureInfo | Select-Object *


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Freitag, 14. November 2014 10:43

Alle Antworten

  • Hallo MCGood!

    Du beschreibst dein Problem sehr abstrakt.
    Sind die Namen der Assamblies ein Geheimnis?
    Isst der Text des Namespaces ein Geheimnis?

    Wenn wir diese wissen könne wir die gezielter helfen.
    Für mich hört sich das so an als ob du Assemblies für .NET 2.0 - 3.5 und .NET 4.0- 4.51 meinst !?
    Dort gibt es meistens die Gleichen Assemblies in verschiedenen Versionen.

    Mit dem folgenden Code kannst du auslesen was gerade in der PowerShell  geladen ist:

    # Alle in PowerShell geladenen Assemblies (.dll) auslesen
    $Assemblies = [System.AppDomain]::CurrentDomain.GetAssemblies()
    
    # Anzeigen der Asemblies
    $Assemblies
    
    # Jede Assembly durchlaufen
    $Assemblies | ForEach-Object {
      
      # Aus jeder Assembly die Typen auslesen
      $_.GetTypes() | ForEach-Object {
        
        # aus dem Typen nur die relevanten Infos holen
        $Result = $_ | Select-Object FullName,AssemblyLocation,AssemblyFullName
        # Assembly informationen "nach vorne holen" 
        $Result.AssemblyLocation = $_.Assembly.Location
        $Result.AssemblyFullName = $_.Assembly.FullName
        # Resultat in die Pipeline ausgeben
        $Result 
      }
    
    } | Format-List

    Im Datei Ordner des Globalen Assembly Cache (GAC) könne mehrere Versionen von ein und derselben Assembly (.dll) liegen.

    Zitat Wikipedia Global Assembly Cache >>
    Die Identität einer Assembly setzt sich aus fünf Komponenten zusammen: dem Namen, der Dateiversion, der Sprachversion, dem öffentlichen Schlüsseltoken und der Prozessorarchitektur, für die die Assembly übersetzt wurde. Die Identität der Assembly wird über einen so genannten „starken Namen“ gesichert. Dabei wird der Name durch die Signierung der Assembly mit einem öffentlichen Schlüssel geschützt. Es ist möglich eine Assembly durch Signierung mit unterschiedlichen Schlüsseln mehrfach im GAC zu installieren. Somit kann z. B. ein Softwarehersteller eine quelloffene Bibliothek verändern (patchen) und mit seinen eigenen Keys signieren. Diese Assembly kann dann trotz gleichem Namen und Versionsnummer im GAC neben der ursprünglichen Assembly installiert werden. Lokalisierte Versionen wie z. B. für Deutsch oder Französisch (DE, FR) ist ebenso Teil der Identität der Assembly, wie die Optimierung auf eine Prozessorplattform (CIL(MSIL), x86, x64).

    Der GAC ermöglicht somit die systemweite Bereitstellung von Assemblies ohne Namenskonflikte der zugrundeliegenden Dateien (DLLs oder EXEs) in Kauf zu nehmen. Die sogenannte DLL Hell wurde durch die Einführung des GAC konsequent umgangen.
    << Ende Zitat siehe: http://de.wikipedia.org/wiki/Global_Assembly_Cache


    Es wird in PowerShell empfohlen  Assemblies mit dem Cmdlet Add-Type zu laden

    Add-Type -AssemblyName Windows.Forms

    Add Type benutzt eine feste Tabelle um zu diesen Partiellen-Namen den richtigen Lang-Namen mit Versions Nummer usw.. zu finden.
     
    Man kann auch die .NET Methode LoadWithPartialName benutzen.
    Dies  wird aber nicht Empfohlen und ist als veraltet markiert!

    [Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')

    Wenn man eine bestimmte Version einer Assembly braucht so muss man dies mit dem Vollen Namen (FullName) der Assembly  tun:

    Add-Type -AssemblyName "Microsoft.SqlServer.SMO, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"

    Siehe auch diesen Artikel:
    How To Load .NET Assemblies In A PowerShell Session
    http://www.dougfinke.com/blog/index.php/2010/08/29/how-to-load-net-assemblies-in-a-powershell-session/


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Donnerstag, 13. November 2014 13:13
  • Hallo Peter,

    vielen Dank für Deine Antwort.

    Die Namen der Assemblies und der Namespace sind keine Geheimnisse, aber drin steckt ein Produktname des Kunden, deshalb wollte ich die Assembly nicht benennen.Das sind also keine Assemblies von Microsoft.

    Wichtig ist, dass die Assembly unterschiedlich heißen. Sie haben beide auch dieselbe .Net-Version.

    Beide haben aber denselben Namespace. Eine Klasse desselben Namen ist auch in beiden Assemblies drin.

    Die beiden Assemblies liegen auch im GAC.

    In die SharePoint Shell sind die beiden Assemblies geladen.

    Daher will ich irgendwie mitgeben, aus welcher geladenen Assemblie ich die Klasse nutzen möchte.

    Donnerstag, 13. November 2014 15:06
  • Ich glaube du bringst einfach die Begriffe Assembly, Namespace und Klasse durcheinander.
    Eine Assembly ist eine .dll die Klassen zu Verfügung stellt.
    Jede Klasse befindet sich in einem Namespace.

    Ein Namespace kann aus mehreren .dlls (Assemblies) bestehen.

    Der Namespace ist eine Pfad angabe zu der Klasse  damit Sie EINDEUTIG angesprochen werden kann.
    Eine Klasse kann nicht doppelt in einem Namespace sein. Der Namespace-Pfad identifiziert die Klasse IMMER eindeutig!

    Die Assemblies sind da völlig Egal, weil die Klasse IMMER über den Namespace angesprochen werden kann!

    In meinem Beispiel oben ist der FullName der Volle Pfad zu Klasse = der Namespace.

    Jetzt kommt es nur noch darauf an, ob du einen Statischen Member der klasse ansprechen willst, oder ob du ein Objekt von der Klasse benutzen möchtest.

    # Methode GetCultureInfo() ist ein statischer Member der Klasse System.Globalization.CultureInfo
    # Statische Member werden über den doppelten Doppelpunkt direkt aus der Klasse heraus angesprochen
    # deutsche Kultur Informationen abrufen. Mit angabe des Namespaces 
    [System.Globalization.CultureInfo]::GetCultureInfo('de-DE') | Select-Object *
    
    
    # Ein Objekt von einer Klasse wir mithilfe des Cmdlets New-Object erzeugt:
    # Ein neues KulturInfo Objekt erzeugen. Mit angabe des Namespaces
    $CultureInfo = New-Object -TypeName System.Globalization.CultureInfo -ArgumentList 'en-US'
    # anzeigen des Inhaltes von dem Objekt
    $CultureInfo | Select-Object *


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Freitag, 14. November 2014 10:43