c# - Hacer referencia a diferentes versiones del mismo ensamblaje
dll build-process (5)
Si A hace referencia al conjunto B 1.1 y C, y C hace referencia a B 1.2, ¿cómo evita los conflictos de ensamblaje?
Originalmente asumí que las referencias de C serían encapsuladas 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 usar 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 las uniones de ensamblaje no me parecen robustas, ¿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 de terceros usa una versión anterior de nHibernate, que yo mismo estoy usando.
El tiempo de ejecución de .NET 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.
He logrado los mismos resultados utilizando el GAC en el pasado, pero debería 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, una redirección vinculante puede ayudar en su caso.
Además, ¿has leído this todavía?
Puede agregar un elemento bindingRedirect 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>
Se me solicitó que admitiera varias versiones de un ensamblaje 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>
Una forma aparentemente poco conocida de hacer esto es usar la palabra clave extern.
Para hacer referencia a dos ensamblados con los mismos nombres de tipo totalmente calificados, se debe especificar un alias en el símbolo del sistema, de la siguiente manera:
/r:GridV1=grid.dll
/r:GridV2=grid20.dll
Esto crea los alias externos GridV1 y GridV2. Para usar estos alias desde dentro de un programa,
extern
utilizando la palabra claveextern
. Por ejemplo:alternar alias GridV1;
alternar alias GridV2;
Cada declaración de alias extern introduce un espacio de nombres de nivel de raíz adicional 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 ensamblaje sin ambigüedad mediante el uso de su nombre totalmente calificado, enraizado en el alias del espacio de nombre 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.