Third party components referencing different versions of the same assembly - c#

In my project I'm using two different third party components.
I don't have access to the source code of these components.
Each component is referencing a different version of the same DLL assembly log4net.
In particular component A is referencing log4net version 1.2.9.0, while component B is referencing log4net version 1.2.10.0.
In VS2012, I'm currently adding to the references of my project the two third party components DLLs and I should add as well a reference to log4net.
I've tried the following:
1) Adding a reference to log4net 1.2.9.0: code compiles but at runtime I get exception "Could not load file or assembly [...] log4net, Version= 1.2.10.0 [...]"
2) Adding a reference to log4net 1.2.10.0: code compiles but at runtime I get exception "Could not load file or assembly [...] log4net, Version= 1.2.10.0 [...]"
3) Renaming the log4net.dll version 1.2.9.0 to log4netOld.dll and adding both the version 1.2.9.0 and the 1.2.10.0 to the project references: during compile time I get an expected warning telling that there is namespace clash, and the compiler resolves the types using 1.2.10.0, so at runtime I get the same problem as point 2 -> code compiles but at runtime I get exception "Could not load file or assembly [...] log4net, Version= 1.2.10.0 [...]"
I'm not expert at all of the Reference properties, our current setting for all references is:
1) alias: global
2) copy local: true
3) embed interop types: false
Any idea about how can I solve the problem ?

You should reference 1.2.10 in your solution and add a binding redirect in the app.config to point 1.2.9 to 1.2.10 - something like this:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.10.0" newVersion="1.2.10.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

Related

How to add dependent assembly without editing webConfig?

So according to my boss we are not allowed to edit the webConfig (I know weird right?). I've added nuGet packages for Microsoft.Owin and other dependent packages. These packages made changes to the webConfig by dependent assemblies to a runtime node.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
...etc...
My question is can I remove the runtime node and its contents but still have the same functionality without removing or changing code? If I remove the node now I get the following error:
Could not load file or assembly 'Microsoft.Owin, Version=2.1.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its
dependencies. The located assembly's manifest definition does not
match the assembly reference. (Exception from HRESULT: 0x80131040)
Whenever you see a bindingRedirect element in your application config file, this means that you have some inconsistency between the versions of the assemblies you are using. The NuGet system automatically detects this inconsistency and adds the binding redirect to ensure that at least you don't get compile time errors. Of course at runtime you might have problems with it because the assembly that depends on the older version of Microsoft.Owin might not work as expected with the one you are redirecting to: especially if there are some breaking changes and it attempts to call a method that no longer exists. The sole fact that you got a binding redirect added in your config file when installing the NuGet means that you might a problem and this problem might manifest only under certain specific circumstances at runtime.
So basically I would start by looking at all dependent assemblies that are references in this project along with their dependencies and try to see where this inconsistency of the versions come from. Then try to eliminate it by finding a newer version of this assembly that works with the latest Microsoft.Owin.

Could not load file or assembly Telerik.Web.UI in ASP.NET

I had telerik version 2012.2.607.35 When I update it to version 2015.2.623.45
I got this error:
Could not load file or assembly 'Telerik.Web.UI,
Version=2012.2.607.35, Culture=neutral, PublicKey
Token=121fae78165ba3d4' or one of its dependencies. The located
assembly's manifest definition does not match the assembly reference.
(Exception from HRESULT: 0x80131040)
I replaced all reference telerik to version 2015.2.623.45 in project references but the error exist yet.
While the assembly binding redirect is a way to solve this, as suggested by the answer, I would advise you to find the fully qualified assembly reference and make it non-fully qualified. It is likely to be a Register directive in the web.config or in a user control. Doing that will make future updates easier, otherwise you will get the same error the next time you upgrade unless you also update the bindingRedirect.
you should define assembly in web.config file
<dependentAssembly>
<assemblyIdentity name="YourDllFile" publicKeyToken="2780ccd10d57b246" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-YourDllFileVersion" newVersion="YourDllFileVersion" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Telerik.Web.UI" publicKeyToken="121fae78165ba3d4" />
<bindingRedirect oldVersion="1.0.0.0-2015.2.600.45" newVersion="2015.2.623.45" />
</dependentAssembly>
I had a similar problem. I checked the version of the .dll in the bin folder on my website and the version throwing the error. Since the code where the error was being thrown was not my own, I realised the version of the .dll was a dependency of 3rd party code. As it turns out the .dll in my bin had been overwritten with an older version.
Solution was to put the correct version of the .dll in the bin folder (since this was installed with the application initially) seems an update failed to install the newer version.

.NET loaded looking for another version of assembly when generate type's for WCF service

I got this error while trying to add service reference to my ASP.NET web application in Visual Studio 2013. I had reference to Microsoft.Owin.Security version 2.1.0.0 in my project. But I'm discouraged why he looking for 2.0.1.0 version?
Cannot import wsdl:portType Detail: An exception was thrown while
running a WSDL import extension:
System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Could not load file or assembly 'Microsoft.Owin.Security,
Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or
one of its dependencies. The system cannot find the file specified.
I did find and post a possible solution on Hélder Gonçalves' version of this question. Hopefully it will allow you to generate the service reference without redirecting to an older version of the Microsoft.Owin.Security assembly. Please let me know if this works for you.
Per Rizier123 suggestion, here's the text from my solution in full:
Had the exact same error verbatim and was able to resolve it by specifying which assemblies to reuse types from.
When adding the service reference, click the Advanced... button in the bottom left corner of the Add Service Reference window. On the Service Reference Settings screen that appears, in the Data Type section, under the Reuse Types in all referenced assemblies: check-box, select the Reuse types in specified reference assemblies radio button then check ONLY the assemblies that contain types used by the service. This should resolve the issue.
The assembly versions that are actually installed and referred varies due to various factors. Anyway you can redirect the binding to your desired versions. Refers this link
In your case, you have to add the following lines to the web.config under configuration
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="'Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.0.1.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>

Assembly binding and redirect

I have an EXE that reference a DLL - for this example I'll call it TestDLL.dll.
The EXE is written in C# and the DLL is written in VB .Net.
I created a demo assembly version of the DLL - for example - TestDLL.dll version 1.0.0.0.
I want to compile the EXE with a reference to the demo version DLL (1.0.0.0). Afterwards - I want the EXE to use the same DLL, but the one I'll put in the GAC, of any version.
In order to do that, I set the "Copy Local" property of the DLL's reference to FALSE.
My goal is for example - after compiling, I'll put in the GAC TestDLL.dll with assembly version 2.1.6.0, and the EXE will find it using the assembly redirect binding. For that, I used a config file. I used this link to create it:
http://msdn.microsoft.com/en-us/library/7wd6ex19(v=vs.71).aspx
So my config file looks about like this:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="en-us" />
<!-- Assembly versions can be redirected in application, publisher policy, or machine configuration files. -->
<bindingRedirect oldVersion="1.0.0.0"
newVersion="2.1.6.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
The problem is that after doing all that, I run the EXE and when accessing the dll, I get the famous error:
System.IO.FileNotFoundException: Could not load file or assembly 'TestDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9d8162944bd6fdc7' or one of its dependencies. The system cannot find the file specified.
File name: 'TestDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9d8162944bd6fdc7'
Meaning, the EXE can't find the original DLL I referenced to.
I know that I can just "reference" the GAC or use reflection, but I don't want to - since this EXE is supposed to work only this way.
Does anyone know what's the problem and how to fix it?
Thanks
Make sure that you have set the proper publicKeyToken. In the code you have shown you are using publicKeyToken="32ab4ba45e0a69a1" which is the public key token from the MSDN link. This obviously is not the public key token of your assembly. For this to work you need to have both assemblies (1.0.0.0 and 2.1.6.0) signed with the same key. To extract the public key token you could use the sn.exe tool or looked at the exception stack trace you are getting (it is telling you that publicKeyToken="9d8162944bd6fdc7"):
sn.exe -Tp myassembly.dll
But if the assembly that the executable was compiled against was not signed with the same key this won't work.
Also I see that you have set the culture="en-us" but does your assembly use this culture? You could also try culture="Neutral".
Finally make sure that you have deployed the proper version of the assembly into the GAC.

How can you make a c# project ignore the version number of an assembly?

I am working on a project that references dlls from another product. The product has a release each year and the assemblies version changes for each one, although the methods stay the same.
When I run a build of my project for 2010 when I try and run it for 2009 it throws an error because it is dependent on a different version. Is there a way around this?
If you're referring to a problem at runtime after swapping versions of your assembly without performing a rebuild of the program referencing your newly built assembly, you'll want to use a <bindingRedirect> directive to your program's App.config (or Web.config, if you're talking about a web site.)
bindingRedirect is used to instruct the .NET Framework that it's OK to use a version of an assembly other than the one the application was originally compiled against. By default, the CLR wants to see the same version of a DLL that your application was referencing during build, and if it doesn't it will throw an exception.
Try selecting the reference, and in property window set Specific Version as false.
It is possible to map different .net version of assembly in app.config that you put in application root folder
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Waters.ACQUITY.Remote"
publicKeyToken="6c13fd0b3604de03"
culture="neutral" />
<bindingRedirect oldVersion="1.40.0.0"
newVersion="1.60.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
This is solution when assembly you have referenced has references inside it to another specifc library version.
It happens when at compilation time "Specific version" is set to true. To avoid this problem it should be false.

Categories