.Net NuGet 包冲突 - DLL 地狱又回来了
.Net NuGet package conflicts - DLL Hell is back
我有一个 Visual Studio 项目。
它需要 Newtonsoft.Json 库。
它与 Visual Studio 2017 的 NuGet 包管理器一起引用。
实际上版本 10.0.3.
此项目引用了 NuGet 包 LibA 和 LibB。
LibA 使用 Newtonsoft.Json 版本 8,这在 package.nuspec:
中定义
<dependency id="RestSharp" version="105.2.3" />
<dependency id="Newtonsoft.Json" version="8.0.3" />
<dependency id="CommonServiceLocator" version="1.3" />
LibB 使用 NewtonSoft.Json 版本 10,这在 package.nuspec:
中定义
<dependency id="RestSharp" version="105.1" />
<dependency id="Newtonsoft.Json" version="10.0.3" />
当我使用 Visual Studio 2017 的 NuGet 包管理器更新 LibA 包(例如从 1.1 版到 1.2 版)时(关于解决方案)
它按照 .csproj 文件中的预期更新了 LibA 包的引用:
- <HintPath>..\packages\LibA.1.1\lib\net40\MyService.dll</HintPath>
+ <HintPath>..\packages\LibA.1.2\lib\net40\MyService.dll</HintPath>
但它也更新了 Newtonsoft.Json 库的引用:
- <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
- <HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\packages\LibA.1.2\lib\net40\Newtonsoft.Json.dll</HintPath>
和 app/web.config 文件:
- <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
+ <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
它还正确更新了 package.config:
中的 LibA 引用
- <package id="LibA.MyService" version="1.1" targetFramework="net45" />
+ <package id="LibA.MyService" version="1.2" targetFramework="net45" />
但它留下了对 Newtonsoft.Json 库版本的错误引用:
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net47" />
我抱怨两件事:
如果我打开 NuGet 包管理器,它会显示我在当前项目中使用 Newtonsoft.Json 版本 10.0.3:
这不是真的,因为当我在 bin 文件夹中构建解决方案时,它存储了 8.0.3 版
并且无法更新 Newtonsoft.Json,因为它已 "already" 更新。
此外,我的项目和需要版本 10 的 LibB 实际上使用的是版本 8。
我无法决定自动维护版本 10,实际上我必须手动合并和更正所有 .config 和 .csproj 文件 !
有办法避免这个噩梦吗?
额外信息。
该项目和 LibB 在 .Net 4.7 上设置。
LibA 仍在 .Net 4.5 上。
LibA 和 LibB 部署在公司 NuGet 存储库中。
[更新]
正如评论中所建议的那样,我将尽量不在 LibA(和 LibB)包中包含 Newtonsoft.Json 库。实际上它发生是因为这个(我认为):
<files>
<file src="bin$configuration$\**\*.*" exclude="**\*.pdb" target="lib\net40"/>
</files>
我改成这样:
<files>
<file src="bin$configuration$\**\MyCompany.*.*" exclude="**\*.pdb" target="lib\net40"/>
</files>
它有效,Newtonsoft.Json 包取自 NuGet。
您的第一次投诉不正确。 NuGet 包管理器显示 NuGet 包 的版本,而不是 DLL 中嵌入的版本号。您可能会争辩说包管理器应该检测到这一点,但这实际上是由错误的 LibA
包引起的边缘情况。
您对修复的看法是正确的:<file src="bin$configuration$\**\*.*" exclude="**\*.pdb" target="lib\net40"/>
不应使用。
理想情况下,您只包括通过构建项目生成的程序集。如果您包括内部(例如 MyCompany.Common.dll
)或外部(例如 OtherCompany.dll
)的依赖项,您将面临 运行 陷入此问题的风险。将依赖项放在内部 NuGet 服务器上。
我有一个 Visual Studio 项目。
它需要 Newtonsoft.Json 库。
它与 Visual Studio 2017 的 NuGet 包管理器一起引用。
实际上版本 10.0.3.
此项目引用了 NuGet 包 LibA 和 LibB。
LibA 使用 Newtonsoft.Json 版本 8,这在 package.nuspec:
中定义<dependency id="RestSharp" version="105.2.3" />
<dependency id="Newtonsoft.Json" version="8.0.3" />
<dependency id="CommonServiceLocator" version="1.3" />
LibB 使用 NewtonSoft.Json 版本 10,这在 package.nuspec:
中定义<dependency id="RestSharp" version="105.1" />
<dependency id="Newtonsoft.Json" version="10.0.3" />
当我使用 Visual Studio 2017 的 NuGet 包管理器更新 LibA 包(例如从 1.1 版到 1.2 版)时(关于解决方案) 它按照 .csproj 文件中的预期更新了 LibA 包的引用:
- <HintPath>..\packages\LibA.1.1\lib\net40\MyService.dll</HintPath>
+ <HintPath>..\packages\LibA.1.2\lib\net40\MyService.dll</HintPath>
但它也更新了 Newtonsoft.Json 库的引用:
- <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
- <HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\packages\LibA.1.2\lib\net40\Newtonsoft.Json.dll</HintPath>
和 app/web.config 文件:
- <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
+ <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
它还正确更新了 package.config:
中的 LibA 引用 - <package id="LibA.MyService" version="1.1" targetFramework="net45" />
+ <package id="LibA.MyService" version="1.2" targetFramework="net45" />
但它留下了对 Newtonsoft.Json 库版本的错误引用:
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net47" />
我抱怨两件事:
如果我打开 NuGet 包管理器,它会显示我在当前项目中使用 Newtonsoft.Json 版本 10.0.3:
这不是真的,因为当我在 bin 文件夹中构建解决方案时,它存储了 8.0.3 版 并且无法更新 Newtonsoft.Json,因为它已 "already" 更新。
此外,我的项目和需要版本 10 的 LibB 实际上使用的是版本 8。我无法决定自动维护版本 10,实际上我必须手动合并和更正所有 .config 和 .csproj 文件 !
有办法避免这个噩梦吗?
额外信息。
该项目和 LibB 在 .Net 4.7 上设置。
LibA 仍在 .Net 4.5 上。
LibA 和 LibB 部署在公司 NuGet 存储库中。
[更新]
正如评论中所建议的那样,我将尽量不在 LibA(和 LibB)包中包含 Newtonsoft.Json 库。实际上它发生是因为这个(我认为):
<files>
<file src="bin$configuration$\**\*.*" exclude="**\*.pdb" target="lib\net40"/>
</files>
我改成这样:
<files>
<file src="bin$configuration$\**\MyCompany.*.*" exclude="**\*.pdb" target="lib\net40"/>
</files>
它有效,Newtonsoft.Json 包取自 NuGet。
您的第一次投诉不正确。 NuGet 包管理器显示 NuGet 包 的版本,而不是 DLL 中嵌入的版本号。您可能会争辩说包管理器应该检测到这一点,但这实际上是由错误的 LibA
包引起的边缘情况。
您对修复的看法是正确的:<file src="bin$configuration$\**\*.*" exclude="**\*.pdb" target="lib\net40"/>
不应使用。
理想情况下,您只包括通过构建项目生成的程序集。如果您包括内部(例如 MyCompany.Common.dll
)或外部(例如 OtherCompany.dll
)的依赖项,您将面临 运行 陷入此问题的风险。将依赖项放在内部 NuGet 服务器上。