.net - 为什么我的 .NET Standard NuGet 包会触发这么多依赖项?

标签 .net nuget .net-standard

我一直在胡闹a .NET Standard project和 NuGet。我有一个工作项目并且有 uploaded it to NuGet.org .我的项目面向 .NET Standard 1.3,其中 should support .NET Framework 4.6 和 .NET Core 1.0。

但是当我尝试将我的项目(通过 NuGet)添加到一个新的 .NET Framework 4.6 项目时,依赖项解析为 47 包!它们都是系统库,似乎是 Microsoft.NETCore.Platforms 或 NETStandard.Library 1.6.1 的依赖项。 ( Gist of full PM output. )

我的项目只导入( using )一些库,我没有手动添加;即它们都是“附带”.NET Standard 的库。这些库是:

  • 系统
  • System.Text
  • System.Reflection
  • System.Linq
  • System.Collections.Generic;

  • 问题是,我决定让我的项目以 .NET Standard 为目标,因为我希望它能够在 .NET Framework 和 .NET Core 应用程序之间无缝工作。我认为标准的全部意义在于设置最低级别的兼容性。通过扩展,我想我已经假设(可能是错误的)像 System.Console 这样的库将在 Core 或 Framework 中自动可用。

    当我在同一个解决方案中测试我的标准项目作为框架和核心项目中的依赖项时,我没有注意到这样的事情,所以我怀疑这可能是 NuGet 的事情。

    这里到底发生了什么?以及如何在没有大量依赖项的情况下使我的 .NET Standard 库在 NuGet 上可用?

    我指定 NuGet 包的方式有问题吗?或者我从根本上误解了什么?

    最佳答案

    你没有做错任何事,这会发生。如果您只想将自己的 DLL 添加到新的 .NET Framework 项目中,那么您必须将 .NET Standard 2.0 作为您的库的目标,等待 native 支持 API 和程序集版本的 .NET Framework 版本 - 这将会发生为 4.7.2(虽然 .NET Framework 4.7.1 支持所有 API,但某些程序集的版本控制存在错误,因此工具(VS 2017 15.5+)将添加其他程序集来修复该问题)。

    您所看到的是 .NET Standard 的构建方式和对所支持框架的支持的实现方式的副作用。这也根据您的目标 .NET Standard 版本和用于引用库包的工具而有所不同。

    在 .NET Standard < 2.0 中,您引用了 NETStandard.Library meta-package 反过来引用其他( System.* )包。这些包包含构成“.NET 标准契约”的引用程序集 - 一组 API 和程序集名称 + 版本。

    当您为 .NET Standard 1.0-1.6 创建的 NuGet 包随后被应用程序引用时,这些单独的包不会引入引用程序集,而是引入应用程序目标框架的实现程序集。

    对于 .NET Core,这些匹配已经是运行时一部分的程序集,因此 DLL 文件不会在构建的应用程序旁边结束。然而,当为 .NET Core 1.1(NETStandard.Library 1.6.1 版)发布一组新的包时,这种情况发生了变化。这导致为 .NET Core 1.0 构建的应用程序最终获得了本应包含在 .NET Core 1.1 中的更新的实现程序集(幸运的是,1.1 随后成为“长期支持”版本,因为这引发了关于哪些程序集的讨论是 LTS promise 的一部分)。

    在 .NET Framework 上,这些库(除了 System.Net.Http 之类的一些异常(exception))并没有做太多 - 它们只是转发到系统程序集。例如,“契约(Contract)”定义了 System.ObjectSystem.Runtime.dll 中定义集会。所以System.Runtime.dll您最终在 .NET Framework 应用程序中得到的文件包含 System.Runtime.dll包含类型转发到 .NET Framework 的 mscorlib.dll . .NET Core 已经包含一个不同的 System.Runtime.dll这对那个平台做了一些不同的事情。这种机制允许单个 DLL 文件在两个平台上工作,因为这些类型转发和附加实现确保在两个实现上工作的相同“契约(Contract)”(类型 + 程序集 + 程序集版本)。

    .NET Standard 2.0 旨在减少必需的包和 DLL 的数量,并删除对 NETStandard.Library 的要求更新。每当发布新的 .NET Core 版本时。

    因此,对于 .NET Standard 2.0 和 .NET Core 2.0,NETStandard.Library package 仅将用于编译代码的引用程序集带到项目中,但生成的 NuGet 包不再依赖于该包。因此,当您创建面向 .NET Standard 2.0 的库并发布它时,它将没有 NuGet 依赖项(除非您添加其他依赖项)。

    使用 .NET Standard 库时要引入的“支持库”的逻辑已移至构建期间使用的工具。因此,当包含对 netstandard.dll 的引用的库时添加到 .NET Framework 项目后,该工具将根据所使用的 .NET Framework 版本添加必要的支持 DLL。这是为 .NET Standard 2.0 以及 .NET Standard 1.5+ 完成的,因为 .NET Framework 4.6.1 通过这些类型的 DLL 文件追溯兼容 .NET Standard 2.0(之前为 1.4)。相同的工具还确保即使 NuGet 包以某种方式引入到这样的应用程序项目中,通过 NuGet 引入的任何 .NET Standard 实现库也会从构建中删除。因此,如果您引用在 .NET Core 1.0 发布时构建的 .NET Standard 1.0 NuGet 包,则其所有 NuGet 依赖项都将被删除,您将获得随构建工具提供的支持库。

    这个想法是 .NET Framework 4.7.1 将包含所有必要的程序集“收件箱”,以便 netstandard.dll , System.Runtime.dll等是 .NET Framework 的一部分,任何 .NET Standard 1.0-2.0 DLL 文件都可以“正常工作”,问题是这些“收件箱”dll 文件对于某些程序集的版本号太低,因此库将无法加载 -这是通过再次更改工具以包含具有更高版本号的 DLL 文件作为支持库来解决的,这些支持库又转发到“收件箱”.NET Framework 程序集。这计划在 .NET Framework 4.7.2 中修复。

    关于.net - 为什么我的 .NET Standard NuGet 包会触发这么多依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47365136/

    相关文章:

    .net - MVC 5 中的 "CacheProfile"

    .net - 我该如何解决这个错误? "Error occurred during a cryptographic operation."

    c# - 如何在 SQL WHERE 查询中引用 ASP.net 中的变量

    .net - WPF MVVM设置控制焦点

    c# - 如何在没有任何 nuspec 文件的情况下将多个项目的产品打包到一个 nuget 中?

    visual-studio-2010 - 从 Visual Studio 外部使用 NuGet PowerShell 命令行开关

    visual-studio - 如何修复 ChakraCore NuGet 包错误?

    .net-core - 我可以在 netstandard2.0 项目中使用 netstandard1.* 库吗?

    com - 无法使用 COM 加载文件或程序集“Microsoft.Extensions.DependencyInjection.Abstractions”

    asp.net-mvc - .NET 4.7.1 中的 ASP.NET MVC 5 razor View 中引用 netstandard 2.0 类型