How does .NET resolve different versions of the same package?
Asked Answered
A

1

8

This question pertains to .NET 5+, not .NET Framework.

Consider the following dependency tree:

  • MyWebsite has package references to RandomWebLibrary 1.0.0 and RandomJsonLibrary 2.0.0.
  • The NuGet package RandomWebLibrary 1.0.0 has a package reference to RandomJsonLibrary 1.0.0.
  • The NuGet package RandomJsonLibrary has no dependencies.

My questions:

  1. What version(s) of RandomJsonLibrary will be loaded at runtime?
  2. What happens if RandomJsonLibrary 2.0.0 has a completely different API than RandomJsonLibrary 1.0.0?
  3. Can the author of MyWebsite do anything to fix problems that arise from having multiple versions of RandomJsonLibrary in the dependency tree? Is there an equivalent of .NET Framework's binding redirects in .NET 5+?

I'm asking out of curiosity, not because I am encountering a problem. For reference, here is the documentation on Understanding AssemblyLoadContext which seems relevant but did not answer my question.

Angelaangele answered 28/10, 2021 at 1:14 Comment(4)
1) you can write some simple code to find out, 2) then something is going to break, 3) Why would MyWebsite have an explicit dependency on something that is already covered by a child package, which is in direct conflict with?Unreserved
michaelscodingspot.com/assemblies-load-in-dotnetRedfaced
For example, in a simple description, this article may be helpful. Assembly versionWeirdie
Does the NuGet Dependency Resolution Documentation help answer your questions? (e.g. nearest-wins rule)Rianon
A
6

These questions are answered by the documentation page How NuGet resolves package dependencies. The "Dependency resolution with PackageReference" section is what's relevant to this question since we are talking .NET 5+.

When the package graph for an application contains different versions of the same package, NuGet chooses the package that's closest to the application in the graph and ignores all others. This behavior allows an application to override any particular package version in the dependency graph.

In the example below, the application depends directly on Package B with a version constraint of >=2.0. The application also depends on Package A which in turn also depends on Package B, but with a >=1.0 constraint. Because the dependency on Package B 2.0 is nearer to the application in the graph, that version is used:

Application using the Nearest Wins rule

To answer the original questions:

  1. RandomJsonLibrary 2.0.0 will be loaded at runtime.
  2. I believe RandomWebLibrary will throw exceptions at runtime if RandomJsonLibrary 1.0.0 and 2.0.0 have incompatible APIs.
  3. The author of MyWebsite can choose the exact version of any dependent package by installing that package directly into MyWebsite. In the case of RandomJsonLibrary, the author of MyWebsite should probably downgrade to RandomJsonLibrary 1.0.0 to prevent RandomWebLibrary from breaking. AFAIK there are no binding redirects in .NET 5+.
Angelaangele answered 29/10, 2021 at 16:29 Comment(1)
Thank you @martin-ullrich for pointing me to the appropriate documentation. Also, let me know if I got any of the specifics wrong in this answer.Angelaangele

© 2022 - 2025 — McMap. All rights reserved.