Where is the best place to find information on binding redirects? or maybe just a basic explanation of where you put these redirects within a project?
Where you put it can only be configuration. Find details here.
Why not start from the beginning?
after understood what it does, you will end up with something like:
<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>
There are several configuration files that can include binding redirects. Another option besides the configuration files is to use the AppDomain.AssemblyResolve event to decide on redirects at run time. I've included some sample code in this answer.
Related
When calling the System.IO.Compression.Zipfile.CreateFromDirectory, I am met with the following error :
However, my project does contain the first version of the assembly mentioned in the error (seen in the screenshot below).
After searching around, I saw that this error could arise from not having the System.IO.Compression.FileSystem assembly, which this project has :
I tried using / removing the System.IO.Compression.Zipfile assembly (which I found out is just a "link" to System.IO.Compression.FileSystem), changing System.IO.Compression versions, but nothing worked.
This project runs under the .NET Framework 4.6.1.
Does anyone have an idea of how to troubleshoot this one ? Thanks !
In my case I added the following to web.config runtime/assemblyBinding node:
<dependentAssembly>
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
You can manually add the following binding redirect in your application's config file:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.IO.Compression.ZipFile" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Change this
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.Compression.ZipFile.UseBackslash=true" />
</runtime>
To
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.Compression.ZipFile.UseBackslash=false" />
</runtime>
In my assembly I want to use
SomeLibrary.dll -> Newtonsoft.Json, Version 10.0.0.0
where I'm referencing SomeLibrary.dll by path. Then I also have
Microsoft.NET.Sdk.Functions -> Newtonsoft.Json, Version 9.0.0.1
where those are both referenced by Nuget. This causes version mismatch when I do
JsonConvert.DeserializeObject<SomeTypeFromSomeLibrary>(json)
Anything I can do about this? :(
This kind of issue is usually resolved with a binding redirect.
For JSON.NET, it might look something like this:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I have a simple c# application and I would like to reference an assembly from C:\..\..myassembly.dll without copying the thing to bin folder.
I there a way to change how is assembly being referenced/loaded?
Edit: the assembly is not in gac
Actually it is possible during runtime by using <codeBase> tag in your configuration:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyAssembly2" culture="neutral" publicKeyToken="307041694a995978"/>
<codeBase version="1.0.1524.23149" href="FILE://C:/Myassemblies/MyAssembly2.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
You can refer to the MSDN to get more specific info. The downside of this solution is that you have to manually specify assembly version.
Multiple solutions to your problem.
To avoid copying library to output folder set Copy Local to false by selecting .dll property.
Option 1:
Include below section in your configuration file and let allow runtime to load from location you specified.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyAssembly" publicKeyToken="2d65620afb84f19d" />
<codeBase version="1.0.0.0" href="C:\..\..myassembly.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Option 2:
Well known option, use reflection to load your assembly.
Assembly.Load(#"C:\..\..myassembly.dll")
Hope this helps !
I've searched a lot but wasn't able to find a solution yet.
We have a lot of programs for our clients with shared libs (dlls) in one directory. But if one lib gets an update we have to recompile all programs which are refering the dll. If we don't, our client get's an error when calling a function from the lib (The located assembly's manifest definition does not match the assembly reference).
We would like to reference a lib as usual and when a lib get's upgraded the programs should just use the new version instead of throwing an error.
Part of the problem is, that the reference is internally fixed with an version-number. My first idea is to remove the version number of the dll before refering. But is that even possible?
I would be grateful for any (other) ideas or suggestions how to bypass the reference problem. This may be a duplicate but I didn't yet find a post with an solution - just post's which describe the reasons.
What about assembly binding redirection - https://msdn.microsoft.com/en-us/library/433ysdt1(v=vs.110).aspx (one more msdn link) ?
You can specify in the config redirection to a new version, so it wont require recompile. But if signature of classes\methods that you are using will be changed - then it will throw an exception anyway.
ASP.Net MVC uses this approach to specify redirection to a new version of MVC:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
I am trying to downgrade a NServiceBus dependency so instead of using 4.0.0.0 to use 2.5.0.0
I am trying with the following ways, none of which seem to work.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NServiceBus"
publicKeyToken="9fc386479f8a226c" culture="neutral"/>
<bindingRedirect oldVersion="4.0.0.0" newVersion="2.5.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
I also tried with codebase :
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NServiceBus"
publicKeyToken="9fc386479f8a226c"
culture="neutral"/>
<codeBase version="2.5.0.0" href="NServiceBus.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
Still, nada. I went through the msdn documentation and there is no mention of using this capability in a backwards way. Is this possible?
I'm actually using your first statement for some interop DLLs because the clients in our company have a different state regarding office updates. This is the code I use :
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="office" publicKeyToken="71E9BCE111E9429C" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-14.0.0.0" newVersion="11.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
This provides backwards compatibility from version 14 of the DLL to version 11. Could you provide a link to the DLL u are using?
I've downloaded the NServiceBus framework (version 3.3.8) and investigated the DLL with ILSpy. I would suggest you do the same with your DLL. For my DLL it shows me the same public Key token as yours. Are you sure, that you use version 4.0.0.0 and not verision 3.3.0.0. Or you missmatched the public Key tokens perhaps.
According to MSDN: https://msdn.microsoft.com/en-us/library/eftw1fys(v=vs.110).aspx
This value can specify an earlier version than oldVersion.
referring to the newVersion attribute of bindingRedirect. Also in the "Remarks" section:
You can also redirect from a newer version to an older version of the assembly.
Their example is:
<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>
I did notice it also mentions something about Explicit assembly binding redirection in an application configuration file requires a security permission, maybe that's affecting you as well?
The answers above are good answers but they are missing important part. And if you read comments, some devs no longer believe this is working. In fact, this is working and working both ways, up version or down
Important: culture
In my experiment, it started to work only when I set culture to neutral. (examples above have 'en-us')
<assemblyIdentity name="..... culture="neutral"/>
In my setup I have WinApp that references Lib1 and Lib3. Lib1 references Lib2 and Lib3. Lib2 references Lib3. And when I push the button, a call propagated all the way from WinApp to Lib3 (both, direct and through chain of libs), and text return displayed on screen. Lib3 is strong named.
Run 1 - no culture set [assembly: AssemblyCulture("")], no binding redirect set - WORKS!
Run 2 - Lower version in Lib3, set binding redirect to 'en-us' - FAIL!
Run 3 - Lower version in Lib3, set binding redirect to 'neutral' - WORKS! Works up-version and down-version.
On other runs - playing with setting [assembly: AssemblyCulture("en-us")] - all attempts failed when AssemblyCulture was not empty. In fact, when set this attribute in WinApp, it wouldn't even compile
Error CS7059: Executables cannot be satellite assemblies; culture should always be empty
So, here we go. Since I don't understand all intricacies of role of the AssemblyCulture I only claim that my experiment only proves that under specific conditions version redirect works fine.
If I didn't get you wrong I have done the same thing with stimulsoft report DDLs which I had the latest version installed but I wanted 2010.3 in my application. but not through the config file and redirecting:
I simply removed the reference from the solution explorer and added the old DLL refrence, then I set the copy Local property and recompiled so that the DLL would go with application in a same directory, every thing works fine. also done it with some other dlls as well.