Reputation: 832
I have a really hard time figuring out how version resolving of transitive dependencies works for the framework "metapackages".
The reason I am asking is that it seems to be each time we pull in an "old" dependency, for instance something that points to netstandard2.0
or 2.1 we end up with a long list of outdated packages (which again is reported by our build pipeline).
As an example:
Given a .net6 class library, created like this:
dotnet new classlib
dotnet add pakage System.Data.SqlClient
The resulting csproj looks like:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
</ItemGroup>
</Project>
That seems like its fine. I have the latest SqlClient and im on .net6 \o/
Now when i execute dotnet list package --outdated --include-transitive
I get the following output:
Project `Outdated` has the following updates to its packages
[net6.0]:
Transitive Package Resolved Latest
> Microsoft.NETCore.Platforms 3.1.0 6.0.3
> Microsoft.Win32.Registry 4.7.0 5.0.0
> System.Security.AccessControl 4.7.0 6.0.0
> System.Security.Principal.Windows 4.7.0 5.0.0
As far as I can tell Microsoft.Win32.Registry
is part of the "shared framework" and would have expected it to use the latest version.
Can anyone explain why it does not use the latest version? Alternatively how I can force dotnet to use the latest version without a direct dependency (if its possible - again i am trying to avoid a LONG list of outdated transient dependencies that exists in the shared framework...).
Upvotes: 7
Views: 1343
Reputation: 832
Going through various NuGet/dotnet Github issues and discussions. It seems like the way NuGet restores dependencies is to blame. It defaults to the lowest version satisfying all requirements.
The "meta" packages are in fact not tied to the SDK version but have direct dependencies on other packages, such as the Microsoft.NETCore.App
which targets Microsoft.NETCore.Platforms
as version 2.2.4
or higher.
Since System.Data.SqlClient
is a .NET Core 3.1 package, it refers Microsoft.NETCore.Platforms
version 3.1.0
(or higher).
Since my project does not have a direct dependency on Microsoft.NETCore.Platforms
well, NuGet chooses the lowest one.
I still really do not understand why the SDK reference does not cause a direct dependency, but I guess that reasoning have drowned in some GitHub issue discussion.
The following contains a description of the resolution strategy: https://learn.microsoft.com/en-us/nuget/concepts/dependency-resolution#dependency-resolution-rules
Long story short - Its currently only possible to get the latest versions with a long list of specific dependencies.
Edit
Maybe a variation is using Central Package Management: https://devblogs.microsoft.com/nuget/introducing-central-package-management/
Upvotes: 4