Hacer referencia a 2 versiones diferentes de log4net en la misma solución

80

Estoy usando NHibernate 2.1.2.400 que hace referencia a log4net 1.2.10.0. En el mismo proyecto, también uso el SDK de contabilidad simple, lamentablemente todavía usa log4net 1.2.9.0.

Entonces puedo hacer que NHibernate funcione si hago referencia a log4net 1.2.10.0 pero el SimplySDK no funciona. Y viceversa...

Supongo que la mayoría de los problemas provienen del hecho de que log4net ha cambiado su clave de ensamblaje. Intenté usar una redirección de enlace sin éxito: las 2 DLL no tienen la misma clave.

Estoy considerando volver a compilar NHibernate para usar log4net 1.2.9.0, pero parece que no es lo correcto y creo que Simply Accounting no actualizará su SDK para usar log4net 1.2.10.0 en el corto plazo.

¿Cuál es la mejor manera de manejar esto? ¿Es posible resolverlo en absoluto?

Joel Gauvreau
fuente
2
Tengo una pregunta muy similar en stackoverflow.com/questions/1744543/… Recurrí a la recompilación. Supongo que este es el advenimiento de dll-hell v2.0.
Sandor Drieënhuizen
1
mientras revisaba su pregunta, encontré stackoverflow.com/questions/2460542/2461746#2461746 que solucionó mi problema.
Joel Gauvreau
¡Excelente! Me preguntaba cómo hacer que CLR se vea en diferentes ubicaciones y el hrefatributo parece funcionar. ¡Gracias por señalar eso!
Sandor Drieënhuizen

Respuestas:

149

Encontré la solución usando esta respuesta a una pregunta similar

Creas 2 carpetas en tu proyecto, una para cada versión de log4net. Coloque cada log4net.dll en su carpeta correspondiente agregando un archivo a la solución (no con agregar referencia). Puede configurar la copia en la propiedad del directorio de salida para copiar siempre, de modo que se copie automáticamente en la carpeta de salida cuando construya.

Luego modifica el archivo app.config agregando algo como esto:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="681549d62126b7b8" />
        <codeBase version="1.2.9.0" href="log4netv1.2.9.0\log4net.dll" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
        <codeBase version="1.2.10.0" href="log4netv1.2.10.0\log4net.dll" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" />
        <codeBase version="1.2.11.0" href="log4net.dll" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

puede obtener el token de clave pública de un ensamblado usando sn -T [nombreEnsamblado]

Joel Gauvreau
fuente
2
Esto también parece funcionar para mí. Eliminé log4net de mi lista de referencias para el proyecto donde se estaba produciendo el conflicto. Además, dado que log4net.dll no está en mis carpetas bin, mis rutas href se parecían más a ".. \ .. \ .. \ .. \ Lib \ NHibernate-2.0.1.GA \ log4net.dll", solo un ruta relativa a donde estará log4net en cada máquina de desarrollo con nuestro sistema de compilación.
jyoungdev
12
No estoy seguro de haber entendido esto: ¿cómo no se obtienen errores de compilación si no se hace referencia a log4net?
guidupuy
2
¡Esto es increíble, solucionaría otros casos en los que una simple redirección de enlace también rompería las cosas debido a cambios en la API!
Rhys Bevilaqua
5
@guidupy puede hacer referencia al log4net que usa su código, pero desactive copyLocal en las propiedades.
Jeff Martin
4
para futuros lectores (una pista que encontré en otra respuesta, pero es prudente publicarla aquí) ... para aplicaciones web (asp.net), la referencia tiene un ajuste: <codeBase version = "1.0.0.0" href = "bin \ folder \ namedll.dll "/>
granadaCoder
7

Puede agregar una exclusión al registro. Simplemente agregue estas claves:

HKEY_LOCAL_MACHINE\Software\Microsoft\StrongName\Verification\log4net,681549d62126b7b8
HKEY_LOCAL_MACHINE\Software\Microsoft\StrongName\Verification\log4net,1b44e1d426115821
HKEY_LOCAL_MACHINE\Software\Microsoft\StrongName\Verification\log4net,669e0ddf0bb1aa2a

Esto hará que el tiempo de ejecución de .net omita la validación para los ensamblados enumerados. En teoría, este es un problema de seguridad, pero dado que la clave privada está a la vista de todos modos, apenas hay impacto.

Joep Beusenberg
fuente
Como dijiste, este es un problema de seguridad. Además, esto implicaría que debe realizar esos cambios en cada estación de trabajo que ejecute el software. En una red empresarial compleja, ese tipo de cosas se suman para crear un gran lío. Prefiero evitarlo tanto como sea posible. Las otras soluciones son autónomas y portátiles.
Joel Gauvreau
Como dije, debido a que las claves privadas están disponibles públicamente de todos modos, no hay ningún problema de seguridad real. Especialmente en una red empresarial, sería más fácil configurar un único Objeto de política de grupo que configurarlo para cada aplicación LOB en uso. Puede configurarlo una vez a nivel de dominio y nunca más tendrá que pensar en ello.
Joep Beusenberg
3

Si la redirección de enlace no funciona y el SDK de contabilidad simple es de código cerrado, una posible solución es volver a compilar NHibernate para usar log4net 1.2.9.0.

Diego Mijelshon
fuente
3
Eso funcionaría, pero tener que construir una versión especial de nhibernate sería más difícil de soportar en el futuro ... gracias.
Joel Gauvreau