无法在两个 NET Standard 项目中合并 NuGet 包可传递依赖项版本 [英] Unable to consolidate NuGet package transitive dependency versions in two NET Standard projects

查看:38
本文介绍了无法在两个 NET Standard 项目中合并 NuGet 包可传递依赖项版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将 EF Core 添加到 NET Standard 项目会引入与其他项目中的 NuGet 包不兼容的传递依赖版本

我有一个包含多个 .NET Standard 2.0 项目的解决方案.

一个项目 A 使用 Google.Protobuf (3.11.2) NuGet 包,这取决于

System.Memory (4.5.3)System.Buffers (4.4.0)System.Numerics.Vectors (4.4.0)System.Runtime.CompilerServices.Unsafe (4.5.2)

其他一些项目也依赖于 System.Memory 并且都使用相同的依赖版本.

另一个项目B使用Microsoft.EntityFrameworkCore (3.1.0)依赖于

的NuGet包

System.Memory (4.5.3)System.Buffers (4.5.0)System.Numerics.Vectors (4.5.0)System.Runtime.CompilerServices.Unsafe (4.7.0)

尽管 System.Memory 版本在这两种情况下都是 (4.5.3),但它依赖于 System.BuffersSystem.Numerics.VectorsSystem.Runtime.CompilerServices.Unsafe 和它们的版本不同.

当我运行使用这些项目的应用程序(使用 Unity IoC 的 Microsoft Prism WPF .NET Framework 4.8 应用程序)时,UnityContainer 抛出以下异常:

<块引用>

System.IO.FileLoadException:无法加载文件或程序集System.Runtime.CompilerServices.Unsafe,版本=4.0.4.1,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"或其依赖项之一.定位的程序集的清单定义与程序集引用不匹配.

在寻找解决方案后,我将其添加到 NuGet.Config 中:

 <add key="DependencyVersion" value="最高"/></config>

%appdata%Nuget.sln 文件的根文件夹中.

我还删除了 %userprofile%.nugetpackages 文件夹.

然后我从项目中删除了 NuGet 包并重新添加了它们,但它们的依赖项与以前的版本相同.

如果我在 Visual Studio 中导航到Manage NuGet Packages for Solution..."并选择Consolidate",它只会显示No packages found"

解决方案

我设法重现了该问题.我创建了两个新的 .net 标准 2.0 项目 类库.

首先我添加了 EF Core.第二次我添加了 Google protobuf.

与您提到的版本相同.

对于 EF 核心,我创建了一个仅从 DbContext 继承的新类.对于 Protobuf,我刚刚创建了一个空类,因为我不熟悉如何使用它.不过,我仍然能够重现该问题.

然后我创建了一个 console app .net framework 4.7.2 引用上述两个项目.

我在控制台应用程序中实例化了这两个类并得到 error System.IO.FileLoadException: 'Could not load file or assembly...

我是如何解决的

我去了所有三个项目并将这一行添加到csproj.

PackageReference

到物业集团.

<TargetFramework>netstandard2.0</TargetFramework><RestoreProjectStyle>PackageReference</RestoreProjectStyle></PropertyGroup>

之后我再次构建并运行,没有出现错误.

请告诉我您的结果.即使我的解决方案对您不起作用,我相信拥有它也是一种很好的做法.

<块引用>

引用奥伦的话.
使用 .NET Standard 要求您使用 PackageReference 来消除大量包"的痛苦,并正确处理传递依赖项.虽然您可以在没有 PackageReference 的情况下使用 .NET Standard,但我不推荐它."

<块引用>

Hanselman 还提到:全"框架项目使用旧的 .csproj 格式,默认情况下,它们使用 package.config 来管理依赖项.较新的项目可以引用包作为一流的引用.因此,我们需要告诉此解决方案中的所有项目将其包管理和恢复为PackageReferences".

这是我的资料来源.

https://www.hanselman.com/blog/ReferencingNETStandardAssembliesFromBothNETCoreAndNETFramework.aspx

https:///oren.codes/2017/04/23/using-xamarin-forms-with-net-standard-vs-2017-edition/

根据来自 github 问题的 Sommen 额外信息更新感谢 Sommen 提供这些额外信息.还要感谢 Immo Landwerth 在 GitHub 上提供此信息.根据 OP jinjinov 的建议,我将按原样提供 Github 页面中已经存在的解决方法,只是为了完整起见.

摘自 GitHub 问题

解决方法

常规 .NET Framework 项目

  1. 启用 自动绑定重定向 根 .NET Framework 应用程序
  2. 确保您的根应用程序项目不使用 packages.config,而是将 PackageReference 用于 NuGet 包:
    • 如果您当前没有 packages.config,只需添加PackageReference.
    • 如果您当前确实有 packages.config,请将内容转换为项目文件中的包引用.语法是这样的:

ASP.NET Web 应用程序和网站

  1. Web 应用程序和网站不支持自动绑定重定向生成.为了解决绑定冲突,您需要双击错误列表中的警告,Visual Studio 会将它们添加到您的 web.config 文件中
  2. 在 Web 应用程序项目中,您应该像上面提到的那样启用 PackageReference.在网站中,您不能使用 PackageReference,因为没有项目文件.在这种情况下,您需要将任何直接或间接项目引用所依赖的所有 NuGet 包安装到您的网站中.

单元测试项目

默认情况下,绑定重定向不会添加到类库项目中.这对于单元测试项目来说是有问题的,因为它们本质上就像应用程序.因此,除了 自动绑定重定向 你还需要指定GenerateBindingRedirectsOutputType:

<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects><GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType></PropertyGroup>

还有一个讨论部分提供了更多信息 ->GitHub 讨论

Adding EF Core to a NET Standard project introduces transitive dependency versions incompatible with NuGet packages in other projects

I have a solution with multiple .NET Standard 2.0 projects.

One Project A uses the Google.Protobuf (3.11.2) NuGet package, that depends on

System.Memory (4.5.3)
    System.Buffers (4.4.0)
    System.Numerics.Vectors (4.4.0)
    System.Runtime.CompilerServices.Unsafe (4.5.2)

A few other projects also depend on System.Memory and all use the same dependency versions.

Another Project B uses Microsoft.EntityFrameworkCore (3.1.0) NuGet package that depends on

System.Memory (4.5.3)
    System.Buffers (4.5.0)
    System.Numerics.Vectors (4.5.0)
    System.Runtime.CompilerServices.Unsafe (4.7.0)

Even though the System.Memory version is (4.5.3) in both cases, it depends on System.Buffers, System.Numerics.Vectors and System.Runtime.CompilerServices.Unsafe and their versions differ.

When I run the application that uses these projects (a Microsoft Prism WPF .NET Framework 4.8 app that uses Unity IoC) UnityContainer throws the following exception:

System.IO.FileLoadException: 'Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.

After searching for a solution I added this to my NuGet.Config:

  <config>
    <add key="DependencyVersion" value="Highest" />
  </config>

In both, %appdata%Nuget and in the root folder of the .sln file.

I also deleted the %userprofile%.nugetpackages folder.

Then I removed the NuGet packages from the projects and added them back again, but their dependecies come with the same versions as before.

If I navigate to "Manage NuGet Packages for Solution..." in Visual Studio and choose "Consolidate" it just says "No packages found"

解决方案

I managed to reproduce the problem. I created two new .net standard 2.0 project class libraries.

On the first I added EF Core. On the second I added Google protobuf.

Both same versions as you mention.

For EF core I created a new class that just inherits from DbContext. For Protobuf I just created an empty class as I am not familiar on how to use it. I was still able to replicate the problem though.

Then I created a console app .net framework 4.7.2 referencing the above two projects.

I instantiated the two classes in the Console App and got error System.IO.FileLoadException: 'Could not load file or assembly...

How I resolved it

I went to all three projects and added this line to the csproj.

<RestoreProjectStyle>PackageReference</RestoreProjectStyle>

to the Property Group.

<PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>

After that I built and ran again and no error appeared.

Please let me know your results. Even if my solution does not work for you, I believe it is good practice to have it.

To quote Oren.
"Using .NET Standard requires you to use PackageReference to eliminate the pain of "lots of packages" as well as properly handle transitive dependencies. While you may be able to use .NET Standard without PackageReference, I wouldn’t recommend it."

Also Hanselman mentions: "The "full" Framework projects are using the older .csproj format and by default, they use package.config to manage dependencies. The newer projects can reference Packages as first-class references. So we need to tell ALL projects in this solution to manage and restore their packages as "PackageReferences.""

Here are my sources.

https://www.hanselman.com/blog/ReferencingNETStandardAssembliesFromBothNETCoreAndNETFramework.aspx

https://oren.codes/2017/04/23/using-xamarin-forms-with-net-standard-vs-2017-edition/

Updated according to Sommen's extra info from the github issues Kudos to Sommen for providing this extra info. Also Kudos to Immo Landwerth for providing this Info at GitHub. I will provide as is the Workarounds that already exist in the Github page just for complecity as advised by the OP jinjinov.

Taken from GitHub Issues

Workarounds

Regular .NET Framework projects

  1. Enable automatic binding redirects in the root .NET Framework application
  2. Make sure your root application project doesn't use packages.config but uses PackageReference for NuGet packages:
    • If you currently don't have packages.config, simply add <RestoreProjectStyle>PackageReference</RestoreProjectStyle>.
    • If you currently do have a packages.config, convert the contents to package references in the project file. The syntax is like this: <PackageReference Include="package-id" Version="package-version" />

ASP.NET web applications and web sites

  1. Web applications and web sites don't support automatic binding redirect generation. In order to resolve binding conflicts, you need to double click the warning in the error list and Visual Studio will add them to your web.config file
  2. In web application projects, you should enable PackageReference like mentioned above. In web sites, you cannot use PackageReference as there is no project file. In that case, you need to install all NuGet packages into your web site that any of the direct or indirect project references depend on.

Unit test projects

By default, binding redirects aren't added to class library projects. This is problematic for unit testing projects as they are essentially like apps. So in addition to what's outlined in automatic binding redirects you also need to specify GenerateBindingRedirectsOutputType:

<PropertyGroup>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>

There is also a discussion section that provides more information -> GitHub discussion

这篇关于无法在两个 NET Standard 项目中合并 NuGet 包可传递依赖项版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆