zwei verschiedene DLLs mit demselben Namespace


70

Ich habe zwei DLL-Dateien, die den gleichen Namespace haben, aber unterschiedliche Methoden und Typen haben. Wie kann ich beide DLLs in meinem Projekt referenzieren und ihre Methoden und Typen verwenden?

Übrigens haben diese beiden DLLs einige Methoden und Typen mit demselben Namen, aber unterschiedlicher Implementierung und einigen eindeutigen Methoden und Typen.


Die erste Frage, die mir in den Sinn kommt, ist, warum Sie zwei verschiedene DLLs für denselben Namespace erstellen.
Searock

2
Er könnte nur versuchen, zwei zu verwenden, die zufällig denselben Namespace verwenden.
Palswim

Ich erschaffe es nicht. Ich schreibe ein Programm, das 2 DLLs verwenden sollte, die ich nicht ändern kann, da sie in ihren Unternehmen stabil sind. Leider haben beide den gleichen Dateinamen und den gleichen Namespace.

Apropos. Diese beiden DLLs haben einige Funktionen und Typen mit demselben Namen und unterschiedlicher Implementierung sowie einige eindeutige Funktionen und Typen.

10
@Searock - Es ist durchaus üblich, dass derselbe Namespace mehrere Assemblys umfasst, auch innerhalb des Frameworks und insbesondere bei Verwendung von Steuerelementen von Drittanbietern.
Slugster

Antworten:


99

Sie müssen nichts Besonderes tun - referenzieren Sie sie einfach und verwenden Sie die Typen. Namespaces können sich problemlos über mehrere Assemblys erstrecken, da es sich nicht wirklich um undurchsichtige Typen handelt. Ein Namespace ist nur eine Möglichkeit, allen darin enthaltenen Typen ein gemeinsames Präfix hinzuzufügen, sodass Sie mehrere Typen desselben Namens unter verschiedenen Namespaces haben können. (Das Framework sieht sie nicht als gleichnamig an, da es den "vollqualifizierten" Namen von allem sieht - an dessen Vorderseite ein Alias ​​und ein Namespace angehängt sind.)

In dem seltenen Fall, dass Sie auf 2 Assemblys verweisen, die dieselben Typnamen und dieselben Namespaces haben (z. B. 2 verschiedene Versionen derselben DLL), können Sie mithilfe eines Alias ​​unterscheiden, welche Assembly für einen bestimmten Typ verwendet werden soll. Der Standardalias für alle Verweise ist global, aber Sie können Ihren eigenen Alias ​​für jede Assembly angeben, wenn Sie darauf verweisen (mithilfe eines Compiler-Schalters - oder verwenden Sie einfach das Eigenschaftenfeld in Visual Studio) - und eine extern alias <name>Klausel oben in Ihrer Codedatei einfügen Wo Sie es verwenden - Sie würden mit verschiedenen Baugruppen auf die Typen zugreifen<name>::MyNamespace.Type


17
Sie können hier lesen extern alias: msdn.microsoft.com/en-us/library/ms173212.aspx
porges

35

Wenn Sie zwei Typen mit genau demselben Namen haben (beachten Sie, dass der Name den Namespace enthält), sich jedoch in verschiedenen DLLs befinden und beide verwenden möchten, können Sie dies tun.

Kurze Antwort

Sie haben Acme.Foo2 verschiedene DLLs eingegeben und möchten diese verwenden. Geben Sie der Referenz im Fenster mit den Referenzeigenschaften (Ansicht | Eigenschaftenfenster) einen Alias ​​und verwenden Sie ihn wie folgt:

extern alias TheAliasYouGaveTheReference

TheAliasYouGaveTheReference::Acme.Foo f = new 
    TheAliasYouGaveTheReference::Acme.Foo();

Der Standard-Namespace gilt globalfür jedes C # -Programm. Beachten Sie jedoch, dass wir anstelle des von uns erstellten Alias ​​den Alias ​​verwenden global.

Der beste Ansatz ist, NICHT in eine solche Situation zu geraten. Wenn beide Assemblys Ihre eigenen sind, erstellen Sie keine zwei Typen mit genau demselben Namen im genau gleichen Namespace. Aber manchmal kontrollieren wir den Quellcode nicht, so dass für diese Zeiten die obige Lösung verwendet werden kann.

Lange Antwort

Ich kopiere den größten Teil des Artikels von hier, sodass er hier aufgezeichnet wird, falls der Artikel nicht mehr verfügbar ist.

Wie kommst du in eine solche Situation?

Zunächst können Sie das Szenario wie folgt replizieren, damit wirklich klar ist, wovon wir sprechen:

  1. Erstellen Sie eine C # -Klassenbibliothek mit dem Namen FooVersion1
  2. Ersetzen Sie den Vorlagencode in Class1.cs durch Folgendes:

    using System;
    
    namespace Acme
    {
        public class Foo
        {
            public void Bar()
            {
                Console.WriteLine("Bar");
            }
        }
    }
    
  3. Klicken Sie im Solution Explorer mit der rechten Maustaste auf die Lösung und wählen Sie Hinzufügen | Neues Projekt

  4. Speichern Sie das aktuelle Projekt (gilt nur für Express)
  5. Wählen Sie im neuen Projektdialog eine Klassenbibliothek aus, ändern Sie den Projektnamen in FooVersion2 und drücken Sie OK
  6. Ersetzen Sie den Code in Class1.cs durch Folgendes:

    using System;
    
    namespace Acme
    {
        public class Foo
        {
            public void Bar()
            {
                Console.WriteLine("Bar");
            }
    
            public void Goo()
            {
                Console.WriteLine("Goo");
            }
        }
    }
    

Verwendung des Typs in der Anwendung

Ok, jetzt haben wir 2 verschiedene Baugruppen mit Acme.Foo. Lassen Sie uns nun eine Konsolenanwendung erstellen und versuchen, jede zu verwenden.

  1. Klicken Sie im Solution Explorer mit der rechten Maustaste auf die Lösung und wählen Sie Hinzufügen | Neues Projekt
  2. Wählen Sie eine Konsolenanwendung aus und nennen Sie sie Consumer
  3. Klicken Sie mit der rechten Maustaste auf Consumer und wählen Sie "Als Startprojekt festlegen".
  4. Klicken Sie im Consumer-Projekt mit der rechten Maustaste auf den Referenzknoten und wählen Sie "Referenz hinzufügen".
  5. Klicken Sie auf die Registerkarte Projekte und wählen Sie FooVersion1 und FooVersion2 aus. Klicken Sie auf OK
  6. Fügen Sie im Programmtyp des Consumer-Projekts die folgende Zeile zu Main hinzu:

    Acme.Foo f = new Acme.Foo();
    

Erstellen Sie die Lösung über Strg + Umschalt + B (oder F6). Beachten Sie, dass zwei Erstellungsfehler angezeigt werden [wie unten gezeigt]:

Geben Sie hier die Bildbeschreibung ein

Die Reparatur

So können wir das beheben:

  1. Öffnen Sie den Solution Explorer und wählen Sie FooVersion1 im Ordner References des Consumer-Projekts aus
  2. Drücken Sie F4 (oder wählen Sie Ansicht | Eigenschaftenfenster).
  3. Ändern Sie die Aliases-Eigenschaft in FooVersion1
  4. Erstellen Sie die Lösung
  5. Jetzt wird alles korrekt erstellt, da Acme.Foo eindeutig auf FooVersion2 verweist
  6. Fügen Sie die folgende Anweisung oben in Program.cs im Consumer-Projekt hinzu:

    extern alias FooVersion1;
    
  7. Ändern Sie die Verwendung von Acme.Foo in:

    FooVersion1::Acme.Foo f = new FooVersion1::Acme.Foo();
    f.Bar();
    
  8. Beachten Sie dies, wenn Sie 'f' eingeben. Die Abschlussliste enthält nur die Methoden in FooVersion1 von Acme.Foo (insbesondere enthält sie nicht Goo).

  9. Erstellen Sie die Lösung und alles wird korrekt erstellt
  10. Fügen Sie abschließend den folgenden Code unter f.Bar () in Program.cs des Consumer-Projekts hinzu:

    Acme.Foo f2 = new Acme.Foo();
    f2.Goo();
    
  11. Beachten Sie, dass die Abschlussliste von f2 Goo enthält.

  12. Erstellen Sie erneut mit Strg + Umschalt + B und beachten Sie, dass immer noch keine Erstellungsfehler vorliegen

1
Vielen Dank! Ich habe die AliasImmobilie noch nie verstanden und frühere Suchanfragen ergaben keine Ergebnisse.
Thomas Eyde

5

können Sie die Alias - Funktion der / Referenz (Metadaten importieren) (C # Compiler - Optionen) Compiler - Option verwenden , um Ihre Probleme zu lösen, von Lesen Sie hier , um weitere Informationen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.