Referencing 2 different versions of log4net in the same solution

I'm using NHibernate 2.1.2.400 that is referencing log4net 1.2.10.0. In the same project, I also use the simply accounting SDK, sadly it is still using log4net 1.2.9.0.

So I can get NHibernate to work if I reference log4net 1.2.10.0 but the simplySDK don't work. And vice versa...

I'm guessing most of the problems come from the fact that log4net has changed its assembly key. I tried using a binding redirection without success: the 2 DLLs do not have the same key.

I'm considering recompiling NHibernate to use log4net 1.2.9.0 but it seems like the wrong thing to do and my feeling is that Simply Accounting won't be updating their SDK to use log4net 1.2.10.0 anytime soon.

What is the best way to handle this? Is it possible to resolve at all?

41210 次浏览

If binding redirection doesn't work and the simply accounting SDK is closed source, a possible solution is recompiling NHibernate to use log4net 1.2.9.0.

I found the solution by using this answer to a similar question

You create 2 folders in your project one for each version of log4net. Place each log4net.dll in its corresponding folder by adding an the file to the solution (not with add reference). You can set the copy to output directory property to copy always so that it is automatically copied to the output folder when you build.

Then you modifiy the app.config file by adding something like this:

<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>

you can get the public key token of an assembly by using sn -T [assemblyName]

You can add an exclusion to the registry. Just add these keys:

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

This will make the .net runtime skip validation for the listed assemblies. In theory this is a security issue, but since the private key is out in the open anyway, there's hardly any impact.