2

I'm looking for a simple way to manage NuGet packages for the whole solution, to prevent conflicts between transitive NuGet packages when assembling all files into one installer.

When building a project all direct and indirect dependencies are analyzed and the NuGet resolution picks up the best matching version for each NuGet that is at least the same version as the lowest version and might also create binding redirects if necessary. (all good and fine)

The problem we have lately encountered was when we build the whole solution (200+ projects) at once, the resulting NuGet versions between all top level projects might not be identical. And due to the fact, that all resulting DLL and EXE files are installed into the same program files folder, the application can and will crash at runtime due to version mismatches when loading assemblies.

To better understand this issue I've created this sample repo.

The dependency graph looks like this:

  • Library1
    • Microsoft.IdentityModel.Tokens-5.2.1
  • Executable1
    • System.IdentityModel.Tokens.Jwt-5.3.0 (transitive reference: Microsoft.IdentityModel.Tokens-5.3.0)
    • Library1
    • results in: Microsoft.IdentityModel.Tokens-5.3.0
  • Executable2
    • Microsoft.IdentityModel.Tokens-5.2.1
    • results in: Microsoft.IdentityModel.Tokens-5.2.1

To demonstrate the problem, all projects compile to the same bin folder. When the whole solution is compiled and Executable2 is started, the application crashes, since the application expects Microsoft.IdentityModel.Tokens in version 5.2.1 but the actual version is 5.3.0.

For this constructed sample it is easy to find the problem and fix it with updating the Microsoft.IdentityModel.Tokens NuGet to the same version. (Manually, since Visual Studio Package Manager does not recognize this conflict in the consolidate tab).

But at a much greater scale it is far more complex to find those mismatches.

What we have found so far

Centrally managing NuGet package versions

  • Since it is not yet available, it cannot be used to solve the issue here.

Microsoft.Build.CentralPackageVersions

  • Unfortunately there is no IDE support for it, which makes managing NuGet packages very uncomfortable, which I would like to avoid if possible.

So my question is what is the best approach to avoid NuGet version conflicts between projects within the same solution?

Michael Dietrich
  • 451
  • 1
  • 5
  • 17
  • We have the same problem. Have you ever found a solution beyond "Paket package manager"? – Alex I Aug 11 '21 at 04:55
  • Hi @AlexI, sorry for the late response. We finally chose to go with CPVM even it is still in preview. We did not want to use Paket since it does not integrate as good as the built-in tooling. CPVM does its job but unfortunately they removed transitive pinning in .NET 5 from it but might to bring it back in .NET 6. Depending on the framework you use, you could also go with CPVM to resolve this. open issue: https://github.com/NuGet/Home/issues/10389 – Michael Dietrich Aug 21 '21 at 08:14

1 Answers1

0

We've experienced the same problem with some of our projects. We've been using Paket package manager since a couple of years and this has resolved that issue for us.

In short: you define on your solution level which packages you want to use in a file called 'paket.dependencies'. You can be very specific about versions, or let packet use the latest greatest. Then you can specify per project which NuGet package you want to use within that project in a 'paket.references' file. As the name implies, you reference to a package in the paket.dependencies file.

This will make sure, all references packages in your project will use the same package version. I hope this suits your needs as well.

Thomas Luijken
  • 657
  • 5
  • 13
  • Thank you. Does this also apply to transitive dependencies? E.g. if there is a NuGet A and a NuGet B and both use NuGet C, but in different versions, do I need to explicitly state NuGet C in the paket files or will this also be resolved correctly for the whole solution? – Michael Dietrich Jun 02 '20 at 14:20
  • Yes it does. The process is described in the GitHub readme. https://github.com/fsprojects/Paket – Thomas Luijken Jun 02 '20 at 14:47