¿Es posible que dos DLL entren en conflicto, evitando que se cree una solución?

9

Aunque tengo un caso específico, me preguntaba sobre la situación general.

¿Pueden dos DLL, cuando se agregan como referencia a un proyecto de Visual C #, colisionar entre sí para evitar que se construya la solución? Si este es el caso, ¿cuáles son las posibles formas de mitigar esto?

Shamim Hafiz
fuente

Respuestas:

13

Esto es muy posible

Si ha definido un espacio de nombre y un nombre de tipo idénticos en diferentes ensamblajes (o en su proyecto y el ensamblado agregado), obtendrá un conflicto con cualquier código que intente utilizar uno u otro de estos tipos.

Si se asegura de tener espacios de nombres únicos, al igual que sus referencias, no tendría este problema.

Otra posibilidad tiene que ver con diferentes versiones de una dependencia: si su proyecto usa (por ejemplo) una biblioteca de registro en la versión 1.2, pero el ensamblado agregado tiene una dependencia en el mismo ensamblaje pero una versión diferente (digamos 1.3) y su proyecto o el ensamblado agregado se ha configurado / creado para usar una versión específica, obtendrá un conflicto y la compilación fallará.

Ambos problemas se pueden resolver utilizando alias de ensamblaje, como se describe aquí .

Oded
fuente
No estoy completamente seguro de que esto sea cierto. Si observa el CIL, el CLR se refiere a símbolos explícitamente dentro de ciertos conjuntos con la notación [conjunto] antes de cada símbolo. Es posible que el compilador de C # haga cumplir este problema, pero no creo que sea una restricción de la plataforma.
Yam Marcovic
@Yam Marcovic, ¿cómo averiguaría el compilador qué espacio de nombres está tratando de usar en una clase en particular? Los conflictos de nombre de clase completamente calificados definitivamente van a evitar una compilación.
Jeremy
El compilador de C # le ofrece una opción para los alias de ensamblaje, cuando se trata de ensamblajes con el mismo nombre (y posiblemente con los mismos símbolos definidos). Ver stackoverflow.com/questions/517058/…
Yam Marcovic
@Yam: es cierto, sin embargo, debe conocer esta bandera y usarla. Simplemente agregar el ensamblaje rompería la construcción.
Oded
1
Obviamente. Es por eso que él viene aquí por ayuda, ¿verdad? Quiere saber acerca de esta bandera y usarla, porque le dará una solución más limpia, sin afectar su proyecto o las utilidades de terceros.
Yam Marcovic
4

Como nadie más mencionó esto, preguntaste:

¿Cuáles son las posibles formas de mitigar esto?

Hay una solución limpia solo para este caso, sin restricciones y sin soluciones molestas. Puede definir alises de ensamblaje para que el compilador sepa a cuáles referirse en el lugar correcto.

Echa un vistazo a http://blogs.msdn.com/b/ansonh/archive/2006/09/27/774692.aspx

Ñame Marcovic
fuente
3

Sí, esto es muy posible.
Supongamos que agregó una referencia a alguna DLL que usa la versión anterior de Lucene.Net y desea incluir la última versión.
Puede resolver ese problema utilizando alias externos: http://msdn.microsoft.com/en-us/library/ms173212.aspx

šljaker
fuente
+1 esta parece ser la respuesta correcta, ¿qué tal el alias "externo"?
Jalayn
1

Puede colocar tantas versiones diferentes de un ensamblaje como desee en la Caché de ensamblados global, siempre que tengan un nombre seguro . Esto puede ayudarlo si desea que diferentes aplicaciones utilicen diferentes versiones de un ensamblaje, en términos de máquina. Sin embargo, el uso de diferentes versiones de un ensamblaje en UNA aplicación aún lo meterá en problemas.

¿Cuál es la razón por la que necesita ambas versiones al mismo tiempo?

Jalayn
fuente
1
Bueno, no estoy agregando explícitamente diferentes versiones. Básicamente tengo una aplicación WPF. Ahora, para agregar una función de terceros, he agregado algunas DLL y son estas DLL las que pueden estar en conflicto.
Shamim Hafiz
1
De acuerdo, ¿entonces quizás pueda agregar estas DLL relacionadas con terceros al GAC? Ha pasado mucho tiempo desde que leí sobre esas cosas, pero sospecho que esto podría resolver su problema.
Jalayn
¿Qué se entiende por GAC aquí?
Shamim Hafiz
1
Caché de la Asamblea Global, ver msdn.microsoft.com/en-us/library/yf1d93sz%28v=vs.71%29.aspx
Jalayn
0

Sin lugar a duda. Puede obtener el error del compilador "Referencia ambigua" cuando no se pueden distinguir dos objetos. Por lo general, puede especificar la ruta completa en el código y no causará un problema, pero si los dlls fueran completamente idénticos, no podría distinguir entre dos objetos de ninguna manera. Sya tenemos dos dlls:

System.IO que contiene la clase File

y

MyProject.IO que contiene una clase de archivo

Si tuviera algo como esto ...

using System.IO;
using MyProject.IO;

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

... tendría una referencia ambigua, ya que no hay forma de saber de qué archivo está hablando. Esto lo solucionaría:

using System.IO;
using MyProject.IO;

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

La única forma en que sería difícil de solucionar sería si la ruta del "Archivo" fuera idéntica en ambos ensamblajes, pero eso requeriría la situación poco probable de que dos dlls tuvieran una estructura de espacio de nombres idéntica. Por ejemplo, mi situación anterior nunca sucedería, ya que nadie va a nombrar allí el proyecto "Sistema" (con la excepción de los desarrolladores reales del marco .Net).

Morgan Herlocker
fuente
En realidad, sucede mucho si creas soluciones basadas en bibliotecas populares de terceros. Por ejemplo, las bibliotecas de Twitter pueden depender de una versión anterior de su json lib
Hoàng Long