无法在两个 NET Standard 项目中合并 NuGet 包可传递依赖项版本

Jin*_*nov 9 c# prism unity-container visual-studio entity-framework-core

将 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)
Run Code Online (Sandbox Code Playgroud)

其他一些项目也依赖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)
Run Code Online (Sandbox Code Playgroud)

即使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, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 或其依赖项之一。定位的程序集的清单定义与程序集引用不匹配。

搜索解决方案后,我将其添加到 NuGet.Config 中:

  <config>
    <add key="DependencyVersion" value="Highest" />
  </config>
Run Code Online (Sandbox Code Playgroud)

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

我也删除了%userprofile%\.nuget\packages文件夹。

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

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

pan*_*ohn 11

我设法重现了这个问题。我创建了两个新的.net standard 2.0 project类库。

首先我添加了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.

<RestoreProjectStyle>PackageReference</RestoreProjectStyle>

到物业集团。

<PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

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

请让我知道你的结果。即使我的解决方案对您不起作用,我相信拥有它也是一种很好的做法。

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

Hanselman 还提到:“完整的”Framework 项目使用旧的 .csproj 格式,默认情况下,它们使用 package.config 来管理依赖项。较新的项目可以将 Packages 引用为一级引用。所以我们需要告诉所有项目在此解决方案中将其包管理和恢复为“PackageReferences”。

这是我的消息来源。

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

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

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

摘自GitHub 问题

解决方法

常规 .NET Framework 项目

  1. 在根 .NET Framework 应用程序中启用自动绑定重定向
  2. 确保您的根应用程序项目不使用packages.configPackageReference用于 NuGet 包:
    • 如果您目前没有packages.config,只需添加 <RestoreProjectStyle>PackageReference</RestoreProjectStyle>.
    • 如果您当前确实有packages.config,请将内容转换为项目文件中的包引用。语法是这样的: <PackageReference Include="package-id" Version="package-version" />

ASP.NET Web 应用程序和网站

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

单元测试项目

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

<PropertyGroup>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

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