Reputation: 3885
I am being confused by how dependencies are resolved when using a group-based dependency specification in NuGet.
I have a Visual Studio project targeting .NET Framework 4.6.1, with a NuGet dependency to a NuGet package (internal to my company):
This is in the packages.config
file of my project:
<package id="Name.Of.My.Package" version="2.0.65" targetFramework="net461" />
And this is in the .csproj
file:
<Reference Include="Name.Of.My.Package, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Name.Of.My.Package.2.0.65\lib\net45\Name.Of.My.Package.dll</HintPath>
</Reference>
That package is a multi-targeting package with a group-based dependency specification, which looks like this when I get it straight from the .nuspec
file obtained by opening the packages\Name.Of.My.Package.nupkg
file as an archive:
<dependencies>
<group>
<dependency id="Newtonsoft.Json" version="11.0.2" />
</group>
<group targetFramework=".NETFramework4.0">
<dependency id="Microsoft.Bcl.Async" version="1.0.168" />
</group>
</dependencies>
And the packages\Name.Of.My.Package\lib
folder contains:
So my understanding here is that because my project is in net461, the reference should be added to the net45 version of my package (as seems to be the case if I look at the .csproj file), but more importantly that the only implicit dependency should be to Newtonsoft.
But this happens when I try to remove the Microsoft.Bcl.Async
package in the package manager console:
Uninstall-Package Microsoft.Bcl.Async
Attempting to gather dependency information for package 'Microsoft.Bcl.Async.1.0.168' with respect to project 'Name.Of.My.Project', targeting '.NETFramework,Version=v4.6.1'
Resolving actions to uninstall package 'Microsoft.Bcl.Async.1.0.168'
Uninstall-Package : Unable to uninstall 'Microsoft.Bcl.Async.1.0.168' because 'Name.Of.My.Package.2.0.65' depends on it.
This is happening in the latest version of Visual Studio 2017 (15.8.6).
Upvotes: 0
Views: 665
Reputation: 76920
Erroneous dependency resolving for multi-targeting NuGet package
This is the correct behavior of nuget. As we know, .NET Frameworks
are backwards compatible. Meaning if your project is targeting v4.6
, you can consume packages with lower versions, such as v4.5
, v4.0
.
NuGet's specialty is compatibility checking (if packages are authored correctly ofc) :) NuGet knows the available frameworks are v3.5, v4.0, v4.6 and netstandard1.3. The "nearest" compatible framework with v4.5 is v4.0, so it'll pick the v4.0 assets when you install it.
Source: How to figure out the information of dependency packages for missing frameworks
So nuget will install the dependence "nearest" backwards compatible framework v4.6.1, in you case, the dependency Microsoft.Bcl.Async
will also be installed.
That is the reason why you could not uninstall the package Microsoft.Bcl.Async
when you have package Name.Of.My.Package
installed.
For example, when you add the package Microsoft.AspNet.WebApi.Client 5.2.6
to the .net framework 4.6.1 project, nuget will also add the dependency Newtonsoft.Json (>= 6.0.4)
under the .net framework 4.5:
Check this document for some more details.
Upvotes: 1