2008-10-21 28 views
32

Si el conjunto de referencias B 1.1 y C y C hace referencia a B 1.2, ¿cómo evitar conflictos de ensamblaje?Hacer referencia a diferentes versiones del mismo conjunto

Originalmente asumí que las referencias de C se encapsularían y no causarían ningún problema, pero parece que todas las dll se copian en el contenedor, que es donde ocurre el problema.

Entiendo que las dos formas de evitar esto son utilizar el GAC o los enlaces de ensamblaje. El GAC no parece ser el mejor enfoque para mí, ya que no me gusta asumir que habrá dlls allí, prefiero hacer referencia a dlls desde un directorio lib en mi solución.

Donde los enlaces de ensamblaje no me parecen robustos, ¿qué pasa si una versión del ensamblaje tiene una funcionalidad que la otra no tiene, esto no generará problemas?


En mi caso es porque estoy usando un DLL tercera parte utiliza una versión antigua de NHibernate, que yo estoy usando mi mismo.

+0

yo creo que hay un error tipográfico en el título allí. "lo mismo diferente" debería ser "diferente". :) – Herms

Respuesta

9

He logrado los mismos resultados utilizando el GAC en el pasado, pero debe cuestionar sus razones para tener que hacer referencia a más de una versión y tratar de evitarlo si es posible. Si debe hacerlo, un binding redirect puede ayudar en su caso.

Además, ¿has leído this todavía?

1

Puede agregar bindingRedirect element a su archivo de configuración para especificar qué versión del ensamblado desea usar en tiempo de ejecución.

<configuration> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
      <assemblyIdentity name="myAssembly" 
           publicKeyToken="32ab4ba45e0a69a1" 
           culture="neutral" /> 
      <bindingRedirect oldVersion="1.0.0.0" 
          newVersion="2.0.0.0"/> 
     </dependentAssembly> 
     </assemblyBinding> 
    </runtime> 
</configuration> 
+2

Sí, lo mencioné en mi pregunta, pregunté qué pasa en el caso donde hay una funcionalidad diferente en las asambleas. – Dan

1

El .NET runtime es perfectamente capaz de cargar múltiples versiones del mismo ensamblaje simultáneamente. Sin embargo, si va a abrir esta lata de gusanos, le recomiendo encarecidamente que nombre sus ensamblajes y utilice el esquema de nombres Major.Minor. * Para evitar conflictos de nombres.

No creo que deba pensar en un enfoque único para usar (o no) el GAC. El GAC puede ser realmente agradable si desea utilizar automágicamente la nueva funcionalidad publicada con versiones futuras de una DLL. Por supuesto, esta bendición tiene un costo que puede que las nuevas versiones no funcionen exactamente como tú también las esperas :). Se trata de una cuestión de lo más práctico y de cuánto control tiene sobre lo que se publica en el GAC.

Saludos, -Alan.

7

Una forma aparentemente poco conocida de hacer esto es usar la palabra clave extern.

De C# Reference

Para hacer referencia a dos conjuntos con los mismos nombres de tipo totalmente calificados, un alias debe ser especificado en un símbolo, como sigue:

/r: GridV1 = cuadrícula. dll

/r:GridV2=grid20.dll

Esto crea los alias externos GridV1 y GridV2. Para usar estos alias desde un programa, consúltelos utilizando la palabra clave extern .Por ejemplo:

alternar alias GridV1;

extern alias GridV2;

Cada declaración de alias extern introduce un espacio de nombres adicional de nivel raíz que se asemeja (pero no se encuentra dentro) al espacio de nombres global . Por lo tanto, se puede hacer referencia a los tipos de cada ensamblado sin ambigüedad mediante el uso de su nombre completamente calificado, enraizado en el namespace-alias apropiado.

En el ejemplo anterior, GridV1 :: Grid sería el control de cuadrícula de grid.dll, y GridV2 :: Grid sería el control de cuadrícula de grid20.dll.

+2

Entonces, ¿cómo se usa eso, prácticamente? ¿Qué símbolo del sistema es esto y cómo se puede integrar en un proceso de compilación? – Nyerguds

+1

Esto funciona bien, excepto que los proveedores generalmente no cambian el nombre de la DLL de una versión a otra, por lo que terminas tratando de hacer referencia a dos ensamblajes con el mismo nombre. A Studio no le gusta eso y copia de manera no determinista uno de esos a la carpeta de salida, por lo que esto solo funciona si los dlls tienen diferentes nombres por versión. –

2

yo estaba obligado a soportar múltiples versiones de un ensamblado y encontré esta solución:

<runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
     <assemblyIdentity name="MyAssembly" publicKeyToken="..." /> 
     <codeBase version="1.1.0.0" href="MyAssembly_v1.1.0.0.dll"/> 
     <codeBase version="2.0.0.0" href="MyAssembly_v2.0.0.0.dll"/> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 
Cuestiones relacionadas