È possibile che due DLL entrino in conflitto, impedendo la creazione della soluzione


9

Anche se ho un caso specifico, ma mi chiedevo quale fosse la situazione generale.

Due DLL, se aggiunte come riferimento a un progetto Visual C #, possono collidere tra loro per impedire la creazione della soluzione? In questo caso, quali sono i modi possibili per mitigarlo.

Risposte:


13

Questo è molto possibile.

Se è stato definito uno spazio dei nomi e un nome identici su assiemi diversi (o nel progetto e nell'assieme aggiunto), si verificherà un conflitto con qualsiasi codice che tenti di utilizzare uno o l'altro di questi tipi.

Se ti assicuri di avere spazi dei nomi univoci, così come i tuoi riferimenti non avresti questo problema.

Un'altra possibilità ha a che fare con diverse versioni di una dipendenza: se il tuo progetto utilizza (ad esempio) una libreria di registrazione alla versione 1.2, ma l'assembly aggiunto ha una dipendenza dallo stesso assembly ma una versione diversa (ad esempio 1.3) e il tuo progetto oppure l'assembly aggiunto è stato configurato / costruito per utilizzare una versione specifica, si verificherà un conflitto e la generazione avrà esito negativo.

Entrambi questi problemi possono essere risolti utilizzando gli alias di assembly, come descritto qui .


Non sono del tutto sicuro che questo sia vero. Se si guarda al CIL, il CLR si riferisce esplicitamente ai simboli all'interno di determinati assiemi con la notazione [assembly] prima di ogni simbolo. È possibile che il compilatore C # imponga questo problema, ma non penso che sia un vincolo della piattaforma.
Yam Marcovic,

@Yam Marcovic come potrebbe capire il complier quale spazio dei nomi stai cercando di usare in una particolare classe? I conflitti di nomi di classe pienamente qualificati impediranno sicuramente una compilazione.
Jeremy,

Il compilatore C # fornisce un'opzione per gli alias di assembly, quando si tratta di assembly con lo stesso nome (e possibilmente con gli stessi simboli definiti in essi). Vedi stackoverflow.com/questions/517058/…
Yam Marcovic il

@Yam - Vero, tuttavia, devi conoscere questo flag e usarlo. La semplice aggiunta dell'assembly avrebbe interrotto la generazione.
Oded,

1
Ovviamente. Ecco perché viene qui per chiedere aiuto, giusto? Vuole conoscere questa bandiera e usarla, perché gli darà una soluzione più pulita, senza influire sul suo progetto o sui programmi di utilità di terze parti.
Yam Marcovic,

4

Visto che nessun altro lo ha menzionato, hai chiesto:

quali sono i modi possibili per mitigare questo

Esiste una soluzione pulita solo per questo caso, senza vincoli e senza fastidiose soluzioni alternative. È possibile definire gli alise di assemblaggio in modo che il compilatore sappia a quali fare riferimento nel posto giusto.

Dai un'occhiata a http://blogs.msdn.com/b/ansonh/archive/2006/09/27/774692.aspx


3

Sì, questo è molto possibile.
Supponiamo che tu abbia aggiunto un riferimento ad alcune DLL che utilizzano la vecchia versione di Lucene.Net e che desideri includere l'ultima versione.
È possibile risolvere il problema utilizzando alias esterni: http://msdn.microsoft.com/en-us/library/ms173212.aspx


+1 questa sembra essere la risposta giusta, non è che dire dell'alias "esterno".
Jalayn,

1

È possibile inserire tutte le versioni diverse di un assembly che si desidera nella Global Assembly Cache, purché abbiano un nome sicuro. Ciò può essere d'aiuto se si desidera che applicazioni diverse utilizzino versioni diverse di un assieme, dal punto di vista della macchina. Tuttavia, l'utilizzo di versioni diverse di un assembly in UNA applicazione ti metterà comunque nei guai.

Qual è il motivo per cui hai bisogno di entrambe le versioni contemporaneamente?


1
Beh, non sto aggiungendo esplicitamente versioni diverse. Fondamentalmente ho un'app WPF. Ora, per aggiungere una funzionalità di terze parti, ho aggiunto alcune DLL ed è forse questa DLL in conflitto.
Shamim Hafiz,

1
OK, allora potresti forse aggiungere queste DLL di terze parti al GAC? È da tanto che non leggo queste cose ma sospetto che ciò possa risolvere il tuo problema.
Jalayn,

Cosa si intende per GAC qui?
Shamim Hafiz,


0

Di sicuro. È possibile ottenere l'errore del compilatore "Riferimento ambiguo", quando non è possibile distinguere due oggetti. In genere, è possibile specificare il percorso completo nel codice e non causerà un problema, ma se le DLL fossero completamente identiche, non si sarebbe in grado di distinguere tra due oggetti in alcun modo. Sya abbiamo due dll:

System.IO che contiene la classe File

e

MyProject.IO che contiene una classe File

Se dovessi avere qualcosa del genere ...

using System.IO;
using MyProject.IO;

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

... avresti un riferimento ambiguo, dal momento che non c'è modo di dire di quale file stai parlando. Ciò risolverebbe:

using System.IO;
using MyProject.IO;

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

L'unico modo in cui sarebbe difficile da risolvere sarebbe se il percorso di "File" fosse identico in entrambi gli assembly, ma ciò richiederebbe la situazione improbabile in cui due dll avevano una struttura dello spazio dei nomi identica. Ad esempio, la mia situazione precedente non si verificherebbe mai, dal momento che nessuno nominerà il progetto "Sistema" (ad eccezione degli attuali sviluppatori del framework .Net).


In realtà succede molto, se si creano soluzioni basate su librerie di terze parti popolari. Ad esempio, le librerie di Twitter potrebbero dipendere da una versione precedente della tua json lib
Hoàng Long
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.