Ist es möglich, dass zwei DLLs in Konflikt geraten und die Erstellung einer Lösung verhindert wird?

9

Ich habe zwar einen speziellen Fall, aber ich habe mich über die allgemeine Situation gewundert.

Können zwei DLLs, wenn sie als Referenz zu einem Visual C # -Projekt hinzugefügt werden, miteinander kollidieren, um zu verhindern, dass die Lösung erstellt wird? Wenn dies der Fall ist, wie können dies gemindert werden?

Shamim Hafiz
quelle

Antworten:

13

Das ist sehr gut möglich.

Wenn Sie in verschiedenen Assemblys (oder in Ihrem Projekt und der hinzugefügten Assembly) einen identischen Namespace und Typnamen definiert haben, tritt ein Konflikt mit jedem Code auf, der versucht, den einen oder anderen dieser Typen zu verwenden.

Wenn Sie sicherstellen, dass Sie eindeutige Namespaces haben, wie auch Ihre Referenzen, hätten Sie dieses Problem nicht.

Eine andere Möglichkeit hat mit verschiedenen Versionen einer Abhängigkeit zu tun - wenn Ihr Projekt (zum Beispiel) eine Protokollierungsbibliothek in Version 1.2 verwendet, die hinzugefügte Assembly jedoch von derselben Assembly abhängig ist, jedoch von einer anderen Version (z. B. 1.3) und entweder von Ihrem Projekt Wenn die hinzugefügte Assembly für die Verwendung einer bestimmten Version konfiguriert / erstellt wurde, tritt ein Konflikt auf und der Build schlägt fehl.

Diese beiden Probleme können mithilfe von Assembly-Aliasen behoben werden, wie hier beschrieben .

Oded
quelle
Ich bin mir nicht ganz sicher, ob das stimmt. Wenn Sie sich die CIL ansehen, bezieht sich die CLR explizit auf Symbole in bestimmten Assemblys mit der Notation [Assembly] vor jedem Symbol. Es ist möglich, dass der C # -Compiler dieses Problem erzwingt, aber ich denke nicht, dass es sich um eine Plattformbeschränkung handelt.
Yam Marcovic
@Yam Marcovic Wie würde der Complier herausfinden, welchen Namespace Sie in einer bestimmten Klasse verwenden möchten? Vollqualifizierte Klassennamenkonflikte verhindern definitiv einen Build.
Jeremy
Der C # -Compiler bietet Ihnen eine Option für Assembly-Aliase, wenn Sie Assemblys mit demselben Namen bearbeiten (und möglicherweise dieselben Symbole definiert haben). Siehe stackoverflow.com/questions/517058/…
Yam Marcovic
@Yam - Richtig, Sie müssen jedoch über dieses Flag Bescheid wissen und es verwenden. Das einfache Hinzufügen der Baugruppe würde den Build beschädigen.
Oded
1
Offensichtlich. Deshalb kommt er hierher, um Hilfe zu holen, oder? Er möchte über dieses Flag Bescheid wissen und es verwenden, da es ihm eine sauberere Lösung bietet, ohne sein Projekt oder Dienstprogramme von Drittanbietern zu beeinträchtigen.
Yam Marcovic
4

Da dies niemand anderes erwähnte, fragten Sie:

Was sind die möglichen Wege, um dies zu mildern

Nur für diesen Fall gibt es eine saubere Lösung, ohne Einschränkungen und ohne lästige Problemumgehungen. Sie können Assembly-Alises definieren, damit der Compiler weiß, auf welche er sich an der richtigen Stelle beziehen soll.

Besuchen Sie http://blogs.msdn.com/b/ansonh/archive/2006/09/27/774692.aspx

Yam Marcovic
quelle
3

Ja, das ist sehr gut möglich.
Angenommen, Sie haben einen Verweis auf eine DLL hinzugefügt, die die alte Version von Lucene.Net verwendet, und Sie möchten die neueste Version einschließen.
Sie können dieses Problem mithilfe externer Aliase lösen: http://msdn.microsoft.com/en-us/library/ms173212.aspx

šljaker
quelle
+1 Dies scheint die richtige Antwort zu sein, nicht wie wäre es mit dem Alias ​​"extern".
Jalayn
1

Sie können beliebig viele verschiedene Versionen einer Assembly in den globalen Assemblycache einfügen, sofern diese einen starken Namen haben. Dies kann hilfreich sein, wenn verschiedene Anwendungen maschinell unterschiedliche Versionen einer Baugruppe verwenden sollen. Die Verwendung verschiedener Versionen einer Baugruppe in EINER Anwendung führt jedoch weiterhin zu Problemen.

Was ist der Grund für Sie, beide Versionen gleichzeitig zu benötigen?

Jalayn
quelle
1
Nun, ich füge nicht explizit verschiedene Versionen hinzu. Grundsätzlich habe ich eine WPF-App. Um eine Funktion eines Drittanbieters hinzuzufügen, habe ich einige DLLs hinzugefügt, und diese DLLs stehen möglicherweise in Konflikt.
Shamim Hafiz
1
OK, dann können Sie möglicherweise diese DLLs von Drittanbietern zum GAC hinzufügen? Es ist lange her, dass ich über diese Dinge gelesen habe, aber ich vermute, dass dies Ihr Problem lösen könnte.
Jalayn
Was ist hier mit GAC gemeint?
Shamim Hafiz
1
Global Assembly Cache, siehe msdn.microsoft.com/en-us/library/yf1d93sz%28v=vs.71%29.aspx
Jalayn
0

Sicher. Sie können den Compilerfehler "Ambiguous Reference" erhalten, wenn zwei Objekte nicht unterschieden werden können. Normalerweise können Sie den vollständigen Pfad im Code angeben, was kein Problem verursacht. Wenn die DLLs jedoch vollständig identisch wären, könnten Sie in keiner Weise zwischen zwei Objekten unterscheiden. Sya wir haben zwei DLLs:

System.IO, das die File-Klasse enthält

und

MyProject.IO, das eine Dateiklasse enthält

Wenn Sie so etwas haben würden ...

using System.IO;
using MyProject.IO;

...
private void foo()
{
    File f = new File();
}

... Sie hätten eine mehrdeutige Referenz, da es keine Möglichkeit gibt zu sagen, um welche Datei es sich handelt. Dies würde es beheben:

using System.IO;
using MyProject.IO;

...
private void foo()
{
    MyProject.IO.File f = new MyProject.IO.File();
}

Die einzige Möglichkeit, dies zu beheben, wäre, wenn der Pfad von "File" in beiden Assemblys identisch wäre. Dies würde jedoch die unwahrscheinliche Situation erfordern, in der zwei DLLs eine identische Namespace-Struktur hatten. Zum Beispiel würde meine obige Situation niemals eintreten, da dort niemand das Projekt "System" nennen wird (mit Ausnahme der tatsächlichen Entwickler des .Net-Frameworks).

Morgan Herlocker
quelle
Tatsächlich passiert es sehr oft, wenn Sie Lösungen erstellen, die auf gängigen Bibliotheken von Drittanbietern basieren. Zum Beispiel kann eine Twitter-Bibliothek von einer älteren Version Ihrer json lib abhängen
Hoàng Long