问题描述
我快疯了,我希望这是我忽略的事情.
I am going mad here, and I am hoping that it's something that I've simply overlooked.
我遇到间歇性 FileLoadExceptions
,即使部署之间的代码更改不会更改任何程序集引用,它也会在部署后出现.
I am experiencing intermittent FileLoadExceptions
, which are showing up after deployments even if the code change between deployments doesn't change any assembly references.
查看最近的示例,我看到 FileLoadException
由于 System.IO.Compression
,版本 4.2.0.0
找不到.
Looking at the most recent example of this, I am seeing a FileLoadException
due to System.IO.Compression
, version 4.2.0.0
not being found.
在所有情况下,我们都引用 System.IO.Compression
nuget 包,版本 4.3.0
.
In all cases, we are referencing the System.IO.Compression
nuget package, version 4.3.0
.
查看我们解决方案中的两个项目,我发现了一些非常奇怪的地方.ProjectA
引用 ProjectB
.
Looking at two projects in our solution, I noticed something very strange.
ProjectA
references ProjectB
.
ProjectA
在其 packages.config
文件中有以下参考:
ProjectA
has in its packages.config
file the following reference:
<package id="System.IO.Compression" version="4.3.0" targetFramework="net462" />
ProjectB
在其 package.config
文件中有以下参考:
ProjectB
has in its package.config
file the following reference:
<package id="System.IO.Compression" version="4.3.0" targetFramework="net462" />
当我查看 *.csproj
文件时,我看到了:
When I have a look into the *.csproj
files, I see this:
项目A
:
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..packagesSystem.IO.Compression.4.3.0lib
et46System.IO.Compression.dll</HintPath>
</Reference>`
项目B
:
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..packagesSystem.IO.Compression.4.3.0lib
et46System.IO.Compression.dll</HintPath>
</Reference>`
太好了,在这两种情况下,我们都指向磁盘上的同一个程序集.
Great, we are pointing to the same assembly on disk in both cases.
然而,当我在解决方案资源管理器中查看引用的文件时,我看到了:
Yet, when I look at the referenced file in the Solution Explorer, I see this:
项目A
:
以上内容引用 C:Program Files (x86)Microsoft Visual Studio2019EnterpriseMSBuildMicrosoftMicrosoft.NET.Build.Extensions
et461libSystem.IO 中的文件.Compression.dll
,更重要的是有一个 4.2.0.0
版本,而不是 nuget 包文件夹中的版本.
The above is referencing a file that's in C:Program Files (x86)Microsoft Visual Studio2019EnterpriseMSBuildMicrosoftMicrosoft.NET.Build.Extensions
et461libSystem.IO.Compression.dll
, and more importantly has a version of 4.2.0.0
, rather than the version that's in the nuget packages folder.
项目B
:
上面正确指向了nuget packages版本的程序集,其实就是4.1.2.0
.
The above correctly points to the nuget packages version of the assembly, which is in fact 4.1.2.0
.
重申一下,ProjectA
,它引用 ProjectB
,并且两者都有一个绑定重定向,它执行以下操作:
To reiterate, ProjectA
, which references ProjectB
, and both have a a binding redirect that's doing the following:
<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
?而且,我能做些什么来解决这个问题?
So my question is why is Visual Studio pulling down a version of System.IO.Compression
from a location that is not referenced (directly) by any of our projects? And, what can I do to fix this?
此外,虽然我在本地使用的是 Visual Studio 2019 的(当前)RC 版本,但我们的构建代理(Azure DevOps Pipelines)使用的是 Visual Studio 2017.
Further, while locally I am using the (current) RC version of Visual Studio 2019, our build agents (Azure DevOps Pipelines) are using Visual Studio 2017.
在运行时,我们发现记录了上述异常,并且我们创建 ZIP 文件的处理失败.
At runtime, we find the aforementioned exception logged, and our processing that creates a ZIP file fails.
更新
除此之外,我还进行了一些额外的挖掘,发现了一个绑定重定向,它指向这个程序集的 4.2.0.0
版本.我已将其手动降至 4.1.2.0
,并再次部署到我们的测试环境,并进行一些额外的健康检查以了解我们的进展.
Further to the above, I've done some additional digging, and found a binding redirect that points to the 4.2.0.0
version of this assembly. I've dropped that manually down to 4.1.2.0
, and am deploying again to our test environment with some additional health checks to see how we go.
仍然需要了解我们是如何进入这种状态的,以及为什么 csproj
所指向的内容与解决方案资源管理器中所看到的内容存在差异.
Still remaining to understand how we would have gotten into this state, and why the discrepancies with what the csproj
is pointing to vs. what is seen in the Solution Explorer.
推荐答案
具有相同 nuget 包的项目引用不同版本的程序集
Projects with same nuget package refrencing different version of assembly
这是我们构建 .NET Framework 4.6.x 时的已知问题应用程序.
This is a known issue when we build a .NET Framework 4.6.x app.
那是因为:
这是由于注入了对 NETStandard 2.0 的支持.我们注入新的程序集到 NET 4.6.1 和更高版本的桌面项目中,以便添加支持netstandard2.0.我们现在在目标中执行此操作,而不是包,因为它不再需要引用包建立一个网络标准库.每当我们看到一个引用了 netstandard1.5 或更高版本的库(参见 dotnet/sdk#1386).
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
.
To resolve this issue, we could add binding redirect to those reference to use standard references to System.IO.Compression
and not bring in any Nuget package for System.IO.Compression
. If you still want to use the reference System.IO.Compression
from nuget package, you can delete System.IO.Compression
from the MSBuild tooling.
从 Github 查看更多详细信息:
Check more detail info from the Github:
https://github.com/dotnet/corefx/issues/25773
希望这会有所帮助.
这篇关于具有相同 nuget 包的项目引用不同版本的程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!