C# Assembly Binding Redirects - Newtonsoft.Json
Asked Answered
A

2

7

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

Apuleius answered 14/8, 2019 at 15:45 Comment(7)
Is this a compile time error? If so this might help #21498574Accordingly
No, happens during runtimeApuleius
So this is probably just a typo? XX = "9.0" isn't good enough, version numbers have 4 parts. There was only ever one 9.0.1 version, the author makes a living providing support by incrementing major version numbers really fast, its real [AssemblyVersion] is "9.0.0.0". That looking for an update/rebuilding project C tends to be wise goes without saying, but it probably will work anyway.Poddy
Why are you using version 8 in your own project? I tried creating same example and it is giving exception during runtime, but if you change your own project Newtonsoft.json version to 9(I tried this), for me solution is working fine. Is there any specific reason behind use of version 8 in your own project.Turk
@Adrian, Did you get chance to look into my previous commentTurk
@HansPassant sorry, it is just a typo in the question. Version numbers are correctly setApuleius
@PrasadTelkikar Because, there are other components which requires version 8. If I follow your solution, I may need to refactor the whole project split into 2Apuleius
H
3

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.

Humbuggery answered 16/8, 2019 at 19:36 Comment(1)
Both of you posted the same solution, but I like the more detailed explanation. Will pick this one for answer. So, will consider to upgrade my project from 8 to 9.Apuleius
B
1

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.

Bendicta answered 22/8, 2019 at 13:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.