具有引用不同版本程序集的相同 nuget 包的项目

Projects with same nuget package referencing different version of assembly

我快要疯了,我希望这是我刚刚忽略的事情。

我遇到间歇性问题 FileLoadExceptions,部署后会出现这种情况,即使部署之间的代码更改 不会更改任何程序集引用

查看最近的示例,我看到 FileLoadException 由于 System.IO.Compression,未找到版本 4.2.0.0

在所有情况下,我们都引用 System.IO.Compression nuget 包,版本 4.3.0

查看我们解决方案中的两个项目,我发现了一些非常奇怪的事情。
ProjectA 引用 ProjectB.

ProjectA 在其 packages.config 文件中有以下参考:

<package id="System.IO.Compression" version="4.3.0" targetFramework="net462" />

ProjectB 在其 package.config 文件中有以下参考:

<package id="System.IO.Compression" version="4.3.0" targetFramework="net462" />

当我查看 *.csproj 文件时,我看到了这个:

ProjectA:

<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
  <HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
</Reference>`

ProjectB:

<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
  <HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
</Reference>`

很好,我们在两种情况下都指向磁盘上的同一个程序集。

然而,当我在解决方案资源管理器中查看引用文件时,我看到了:

ProjectA:

以上引用了 C:\Program Files (x86)\Microsoft Visual Studio19\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.IO.Compression.dll 中的文件,更重要的是具有 4.2.0.0 的版本,而不是 nuget 包文件夹中的版本。

ProjectB:

以上正确指向程序集的 nuget 包版本,实际上是 4.1.2.0

重申一下,ProjectA,它引用了 ProjectB,并且两者都有一个绑定重定向,它正在执行以下操作:

<dependentAssembly>
    <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>`

所以我的问题是,为什么 Visual Studio 从一个 没有 被我们任何人(直接)引用的位置拉下 System.IO.Compression 的一个版本项目?而且,我能做些什么来解决这个问题?

此外,虽然我在本地使用 Visual Studio 2019 的(当前)RC 版本,但我们的构建代理(Azure DevOps 管道)正在使用 Visual Studio 2017。

在运行时,我们发现记录了上述异常,并且我们创建 ZIP 文件的处理失败。

更新

除上述内容外,我还进行了一些额外的挖掘,发现了指向此程序集 4.2.0.0 版本的绑定重定向。我已手动将其降低到 4.1.2.0,并再次部署到我们的测试环境,并进行一些额外的健康检查以查看我们的进展情况。

仍然需要了解我们如何进入这种状态,以及为什么 csproj 指向的内容与解决方案资源管理器中看到的内容存在差异。

Projects with same nuget package refrencing different version of assembly

这是我们构建 .NET Framework 4.6.x 应用程序时的 known issue

那是因为:

This is due to the injected support for NETStandard 2.0. We inject new assemblies into NET 4.6.1 and later desktop projects in order to add support for netstandard2.0. We do this in targets now instead of packages because its no longer a requirement to reference a package to build a netstandard library. This injection happens whenever we see a netstandard1.5 or greater library referenced (see dotnet/sdk#1386).

要解决此问题,我们可以将绑定重定向添加到那些引用以使用对 System.IO.Compression 的标准引用,而不是为 System.IO.Compression 引入任何 Nuget 包。如果您仍想使用 nuget 包中的引用 System.IO.Compression,您可以从 MSBuild 工具中删除 System.IO.Compression

从 Github 查看更多详细信息:

https://github.com/dotnet/corefx/issues/25773

希望对您有所帮助。