Assembly 'B, Version=1.0.0.000, Culture=neutral, PublicKeyToken=17863af14b0044da' uses 'C, Version=1.5.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc' which has a higher version than referenced assembly 'C, Version=1.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc'
Ostatnio sam spotkałem się z tym problemem wykorzystując w jednym projekcie możliwości AOP kontenera Autofac i NHibernate. Obydwie biblioteki były zależne od Castle.Core.dll. Zostawiając jedynie jej nowszą wersję kontener działał bez zarzutu, ale NHibernate przy próbie stworzenia proxy do encji rzucał pięknym wyjątkiem:
System.IO.FileLoadException : Could not load file or assembly 'Castle.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Najprostszym rozwiązaniem problemu okazało się zmuszenie NHibernate do wykorzystywanie nowszej wersji Castle.Core poprzez tzw Assembly Binding Redirection. Sprowadza się to do dodania paru linijek w pliku *.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Castle.Core" publicKeyToken="407DD0808D44FBDC" />
<bindingRedirect oldVersion="0.0.0.0-1.2.0.0" newVersion="1.2.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Castle.DynamicProxy2" publicKeyToken="407DD0808D44FBDC" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Dzięki temu działa zarówno Autofac jak i NHibernate, a co najważniejsze nie trzeba nic rekompilować podmieniając zależności u źródła. Należy jednak pamiętać, że sztuczka nie zawsze musi działać. W przypadku braku zgodności między kolejnymi wersjami biblioteki mogą pojawić się inne ciekawsze błędy ;).
Warto również zauważyć, że ta metoda wykorzystywana jest w ASP MVC 2, gdzie w standardowym szablonie dla Web.config istnieje wpis:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
