Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Assembly Binding Redirects - Newtonsoft.Json

I have the following dependency

Project A (owned by me) uses

  1. project_b.dll
  2. Newtonsoft.Json.dll (version 8)

Project B uses

  1. project_c.dll
  2. Newtonsoft.Json.dll (version 9)

Project C uses

  1. Newtonsoft.Json.dll (version 4.5)

Project A calls a method of Project B which will call a method of Project C, then return values back to B, then A

<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-655535.0.0.0" newVersion="XX" />
</dependentAssembly>

I am trying to use assembly binding redirect on Project A. If I set 'newVersion' as 9.0, then the code complains (missing Newtonsoft.jSon.dll 4.5 library). Same thing if I set 'newVersion' as 4.5, then missing Newtonsoft.Json.dll 9.0 library error happens. I tried 'newVersion' value of 8.0 as well. It looks simple, and I thought redirecting should solve the issue. What will be the good solution? Should Project A, B, and C have the same version of Newtonsoft.Json.dll?

Thanks in advance..

like image 735
Adrian Avatar asked Aug 14 '19 15:08

Adrian


2 Answers

The only solution that has an above-average chance of working is for all the libraries to be referencing the same "major" version of the library (8.*, 9.*, etc - the first number). You should then be able to use assembly bindingly redirects to fix up anything smaller than the "major", although it is increasingly common to see the assembly version effectively pinned at majors, to avoid assembly binding redirect hell.

The key point here is that under semver, any change in the "major" should be considered a breaking change, and thus you should not expect code compiled against a different "major" to work correctly, or even at all.

Note: it is technically possible to use assembly binding redirects across majors; you just shouldn't expect it to actually work. If it does: consider it an unexpected bonus.

like image 94
Marc Gravell Avatar answered Oct 19 '22 20:10

Marc Gravell


1. Your own project should not have a lower version than the referenced one, so use 9.0 on project A too.

2. If project C uses a lower version that should not be a problem but do this:

In the csproj add AutoGenerateBindingRedirects to the first property group and remove all redirects in the file.

<PropertyGroup>
  [...]
  <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
  [...]
</PropertyGroup>

Now it should generate a correct redirect when you build the project.

like image 1
horotab Avatar answered Oct 19 '22 18:10

horotab