多目标 NuGet 包的错误依赖解析
Erroneous dependency resolving for multi-targeting NuGet package
我对在 NuGet 中使用 group-based dependency specification 时如何解决依赖关系感到困惑。
我有一个针对 .NET Framework 4.6.1 的 Visual Studio 项目,NuGet 依赖于 NuGet 包(我公司内部):
这是在我的项目的 packages.config
文件中:
<package id="Name.Of.My.Package" version="2.0.65" targetFramework="net461" />
这是在 .csproj
文件中:
<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>
那个包是一个多目标包,具有基于组的依赖规范,当我直接从 .nuspec
文件中获取它时,它看起来像这样打开 packages\Name.Of.My.Package.nupkg
文件作为归档:
<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>
并且 packages\Name.Of.My.Package\lib
文件夹包含:
- net40
- net45
- nestandard2.0
所以我这里的理解是,因为我的项目是net461的,所以引用应该加到我的package的net45版本中(看.csproj文件好像是这样),但更重要的是唯一隐含的依赖应该是 Newtonsoft。
但是当我尝试在包管理器控制台中删除 Microsoft.Bcl.Async
包时会发生这种情况:
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.
这发生在 Visual Studio 2017 (15.8.6) 的最新版本中。
Erroneous dependency resolving for multi-targeting NuGet package
这是 nuget 的正确行为。正如我们所知,.NET Frameworks
是向后兼容的。这意味着如果您的项目面向 v4.6
,您可以使用较低版本的包,例如 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.
来源:
因此 nuget 将安装依赖项 "nearest" 向后兼容框架 v4.6.1,在您的情况下,还将安装依赖项 Microsoft.Bcl.Async
。
这就是为什么在安装了软件包 Name.Of.My.Package
后无法卸载软件包 Microsoft.Bcl.Async
的原因。
比如你在.net framework 4.6.1项目中添加包Microsoft.AspNet.WebApi.Client 5.2.6
时,nuget也会在.net framework 4.5下添加依赖Newtonsoft.Json (>= 6.0.4)
:
查看 this document 了解更多详情。
我对在 NuGet 中使用 group-based dependency specification 时如何解决依赖关系感到困惑。
我有一个针对 .NET Framework 4.6.1 的 Visual Studio 项目,NuGet 依赖于 NuGet 包(我公司内部):
这是在我的项目的 packages.config
文件中:
<package id="Name.Of.My.Package" version="2.0.65" targetFramework="net461" />
这是在 .csproj
文件中:
<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>
那个包是一个多目标包,具有基于组的依赖规范,当我直接从 .nuspec
文件中获取它时,它看起来像这样打开 packages\Name.Of.My.Package.nupkg
文件作为归档:
<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>
并且 packages\Name.Of.My.Package\lib
文件夹包含:
- net40
- net45
- nestandard2.0
所以我这里的理解是,因为我的项目是net461的,所以引用应该加到我的package的net45版本中(看.csproj文件好像是这样),但更重要的是唯一隐含的依赖应该是 Newtonsoft。
但是当我尝试在包管理器控制台中删除 Microsoft.Bcl.Async
包时会发生这种情况:
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.
这发生在 Visual Studio 2017 (15.8.6) 的最新版本中。
Erroneous dependency resolving for multi-targeting NuGet package
这是 nuget 的正确行为。正如我们所知,.NET Frameworks
是向后兼容的。这意味着如果您的项目面向 v4.6
,您可以使用较低版本的包,例如 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.
来源:
因此 nuget 将安装依赖项 "nearest" 向后兼容框架 v4.6.1,在您的情况下,还将安装依赖项 Microsoft.Bcl.Async
。
这就是为什么在安装了软件包 Name.Of.My.Package
后无法卸载软件包 Microsoft.Bcl.Async
的原因。
比如你在.net framework 4.6.1项目中添加包Microsoft.AspNet.WebApi.Client 5.2.6
时,nuget也会在.net framework 4.5下添加依赖Newtonsoft.Json (>= 6.0.4)
:
查看 this document 了解更多详情。