.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" />

我抱怨两件事:

  1. 如果我打开 NuGet 包管理器,它会显示我在当前项目中使用 Newtonsoft.Json 版本 10.0.3:
    这不是真的,因为当我在 bin 文件夹中构建解决方案时,它存储了 8.0.3 版 并且无法更新 Newtonsoft.Json,因为它已 "already" 更新。
    此外,我的项目和需要版本 10 的 LibB 实际上使用的是版本 8。

  2. 我无法决定自动维护版本 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 服务器上。