nugetnuget-spec

NuGet transitive dependencies and floating notation


According to Microsoft's documentation using floating notation with NuGet PackageReference “resolves to the highest existent version that matches the version description” - NuGet Package Version Reference | Microsoft Docs

When you use this approach in a simple scenario it works as expected, e.g. with a single level dependency:

MyApp
  \-- PackageA

with MyApp referencing PackageA with <PackageReference Include="PackageA" Version="1.0.*" /> and the following versions of PackageA in the feed

1.0.1
1.0.2
1.0.3

MyApp resolves the dependency to version 1.0.3 and all is good.

However, I have found this does not work for more complex scenarios which involve transitive dependencies like this:

MyApp
  \-- PackageA
    \-- PackageB

With MyApp referencing PackageA by <PackageReference Include="PackageA" Version="1.0.*" /> and PackageA referencing PackageB by <PackageReference Include="PackageB" Version="2.0.*" />

2.0.1
2.0.2

PackageA 1.0.3 is packaged with a reference to PackageB 2.0.2 and subsequently a new version of PackageB 2.0.3 is added to the feed.

In this scenario when restoring MyApp the referenced version of PackageB doesn’t change even if a new version is available on the feed unless PackageA is also restored and published, so it is not resolving to the highest version.

For what I can see the floating notation works only at build time and when a NuGet package is created the reference is converted to an exact dependency version in the nuspec file, i.e. to <dependency id="PackageB" version="2.0.2" />, and therefore adding new versions of PackageB to the feed without re-packaging PackageA will not result in MyApp getting the latest version matching the floating pattern.

Is this by design?

I cannot see this behaviour mentioned in the documentation. I know I can override this by adding the reference to PackageB with the floating notation to MyApp however I think this is not an elegant solution and to some extent defeats the point of having transitive references, are there better ways to ensure the floating notation is preserved for transitive dependencies?


Solution

  • Turns out that this is a fairly common issue and MS will be looking to implement a solution, more is covered in these two related issues on GitHub:

    Allow users to determine package resolution strategy during package restore - direct or transitive

    Allow to specify version range for packagereferences while using the latests / a specific version during build.