引入 NETStandard.Library 依赖时的 System.* 引用问题

System.* reference troubles when introducing NETStandard.Library dependency(引入 NETStandard.Library 依赖时的 System.* 引用问题)
本文介绍了引入 NETStandard.Library 依赖时的 System.* 引用问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个包含 52 个项目(全部为 net462)的大型解决方案中,我们的一些依赖项的最新版本现在仅针对 NET 标准构建.因此,它们依赖于 NuGet 包 NETStandard.Library,而后者又拖入了许多其他 4.3.x 版本的 System.* 包,这些包通常在 .NET Framework 中自己.

因此,一些项目从 packages 文件夹引用 System.* 库,而其他项目从 .NET Framework 引用 System.* 库.

这会导致众所周知的运行时问题 f.e.:

<块引用>

消息:System.IO.FileLoadException:无法加载文件或程序集System.Net.Http,版本=4.1.1.2,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"或其依赖项之一.找到的程序集的清单定义与程序集引用不匹配.(HRESULT 异常:0x80131040)

深入NETStandard.Library包的依赖关系,我们可以看到这些包中也存在同样的问题:

  • System.Collections.*
  • System.ComponentModel.*
  • System.Console
  • System.Globalization.*
  • System.IO.*
  • System.Linq.*
  • System.Net.*
  • System.ObjectModel
  • System.Reflection.*
  • System.Resources.ResourceManager
  • System.Runtime.*
  • System.Text.*
  • System.Threading.*
  • System.Xml.*

通常通过在其他项目中安装相同的包来解决这个问题,但我们在这里处理很多项目和很多包,我不想盲目地将所有这些依赖项添加到所有 52 个项目中.

这让我想知道是否有人知道一种简单的方法可以从这种情况中恢复并让所有项目从 NuGet 包文件夹中引用正确的包/DLL(如果他们当前使用 NET Framework 内部包).

可以在

  1. 将包的相同版本(在您的情况下为 4.3.0)安装到 ConsoleApp1 项目.

  2. 查看结果:

  1. 重建解决方案.

完成.

<小时>

此外,将软件包版本整合到您的解决方案中是一种很好的做法.相反,您可能会在构建期间遇到版本冲突.或者,更糟糕的是,像 MethodNotFound 这样的运行时错误,因为绑定重定向到另一个版本的依赖项.

<小时>

System.Net.Http 问题的原因如下所述:Broken System.Net.Http 4.1.1-4.3.0 事后分析 在以后如何防止这种情况发生? 2.1

部分<块引用>

因此,我们确定了 2 个有问题的 OOB 包,它们不是平台本身的叶节点,而是依赖于平台 - System.Net.Http 和 System.IO.Compression.

这意味着相同的 System.Net.Http 库包含在 .NET Framework 和 OOB(带外)nuget 包中.一些 nuget 包可以引用它的 nuget 版本.这就是我一开始描述的问题.

因此,您不必修复对所有 System.* 库的引用.仅适用于这两个:System.Net.HttpSystem.IO.Compression.

In a large solution with 52 projects (all net462), the latest version of some of our dependencies are now only built for NET standard. Therefore they depend on the NuGet package NETStandard.Library which in turn drags in a lot of other 4.3.x version of System.* packages which are normally in the .NET Framework itself.

As a result, some projects reference System.* libraries from the packages folder, while others reference System.* libraries from the .NET Framework.

This causes the well-known runtime issue, f.e.:

Message: System.IO.FileLoadException : Could not load file or assembly 'System.Net.Http, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Digging into the dependencies of the NETStandard.Library packages, we can see that the same issue also exists in these packages:

  • System.Collections.*
  • System.ComponentModel.*
  • System.Console
  • System.Globalization.*
  • System.IO.*
  • System.Linq.*
  • System.Net.*
  • System.ObjectModel
  • System.Reflection.*
  • System.Resources.ResourceManager
  • System.Runtime.*
  • System.Text.*
  • System.Threading.*
  • System.Xml.*

Normally this is fixed by installing the same package in the other projects, but we're dealing with a lot of projects and a lot of packages here and I don't want to blindly add all of those dependencies to all 52 projects.

This made me wonder whether anyone knows of an easy way to recover from this situation and to make all projects reference the correct package/DLL from the NuGet packages folder if they currently use the NET Framework internal one.

A simple VS-solution for net462 and net471 demonstrating the problem can be found here

解决方案

In the default project template System.Net.Http is added to the project as a reference, not as a nuget package.

In both of your solutions (4.6.1 and 4.7.1):

  • Project ClassLibrary has a dependency on System.Net.Http as a nuget package.

  • Project ConsoleApp1 has a dependency on System.Net.Http as a simple reference from .NET Framework

So, the issue is not related to Target Framework version.

To fix the issue add the same version of System.Net.Http as a nuget package to all projects (where it is used).

  1. Right-click the solution in Solution Explorer and choose Manage NuGet Packages for Solution...

  2. Switch to Installed tab

  3. Find System.Net.Http in the list, select it.

  4. Check current state:

  1. Install the same version of the package (4.3.0 in your case) to ConsoleApp1 project.

  2. Check the result:

  1. Rebuild the solution.

Done.


Also, it's good practice to have package versions consolidated in your solution. Instead, you could have version conflicts during build time. Or, which is worse, runtime error like MethodNotFound because of binding redirect to another version of the dependency.


The reason for the problem with System.Net.Http is described here: Broken System.Net.Http 4.1.1-4.3.0 post-mortem in section How to prevent such situation in future? 2.1

As a result we identified 2 problematic OOB packages, which are not leaf-nodes in the platform itself, and have dependency from the platform on them - System.Net.Http and System.IO.Compression.

It means that the same System.Net.Http library is shipped within .NET Framework and as OOB (out-of-band) nuget package. And some nuget packages could reference nuget version of it. And here it comes the problem that I described at the very beginning.

So, you don't have to fix references to all System.* libraries. Only for these two: System.Net.Http and System.IO.Compression.

这篇关于引入 NETStandard.Library 依赖时的 System.* 引用问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)