为什么我的.NET标准NuGet包会触发这么多依赖项?

我一直在搞一个.NET标准项目和NuGet。我有一个正在工作的项目,并已上传到NuGet.org。我的项目以.NET标准1.3为目标,它应该支持.NET框架4.6和.NET核心1.0

但是当我尝试将我的项目(通过NuGet)添加到一个新的.NET Framework 4.6项目中时,依赖项解析为47包!它们都是系统库,似乎是Microsoft.NETCore.Platform或NETStandard.Library 1.6.1的依赖项。(完整PM输出的要点。)

我的项目只导入(使用)少数库,没有一个是我手动添加的;i、 它们都是“.NET标准”附带的库。这些图书馆包括:

  1. 系统
  2. 系统文本
  3. 系统反思
  4. 系统Linq
  5. System.Collections.Generic

问题是,我决定将我的项目目标定为.NET标准,因为我希望它能够无缝地跨.NET框架和.NET核心应用程序工作。我认为标准的全部要点是设置一个最低限度的兼容性。通过扩展,我假设(可能是错误的)像System.Console这样的库将在核心或框架中自动可用

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

这到底是怎么回事?我如何才能在NuGet上使用我的.NET标准库,而不必列出大量依赖项

我指定NuGet包的方式有问题吗?还是我根本误解了什么

你没有做错任何事,这是预料之中的事。如果只想将自己的DLL添加到新的.NET Framework项目中,则必须将库的.NET标准2.0作为目标,等待本机同时支持API和程序集版本的.NET Framework版本,即4.7.2(虽然.NET Framework 4.7.1支持所有API,但某些程序集的版本控制存在缺陷,因此该工具(VS 2017 15.5+)将添加其他程序集来解决此问题)

您所看到的是.NET标准的构建方式和对受支持框架的支持的实现方式的副作用。这也因您所针对的.NET标准版本和用于引用库包的工具而异

在.NET Standard<2.0中,您引用了NETStandard.Library元包,而元包又引用了其他(System.*)包。这些包包含构成“.NET Standard Contract”(一组API和程序集名称+版本)的引用程序集

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

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

在.NET Framework上,这些库(除了一些例外,如System.NET.Http)没有太多功能-它们只是转发到系统程序集。例如“合同”定义System.Object是在System.Runtime.dll程序集中定义的。因此在.NET Framework应用程序中得到的System.Runtime.dll文件包含一个System.Runtime.dll,该文件包含转发到.NET Framework的mscorlib.dll的类型。NET核心已经包含一个不同的System.Runtime.dll对该平台执行不同操作。此机制允许单个dll文件在两个平台上工作,因为这些类型转发和附加实现确保在两个实现上工作的“契约”(类型+程序集+程序集版本)相同

.NET标准2.0旨在减少所需的软件包和DLL的数量,并在发布新的.NET核心版本时删除需要更新的NETStandard.Library

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

什么是“支持库”的逻辑在使用.NET标准库时引入已移动到生成过程中使用的工具。因此,当将包含对netstandard.dll的引用的库添加到.NET Framework项目中时,工具将根据所使用的.NET Framework版本添加必要的支持dll。这是为.NET标准库完成的rd 2.0以及.NET标准1.5+,因为.NET Framework 4.6.1追溯性地与.NET标准2.0兼容(以前是1.4)通过这些类型的DLL文件。相同的工具还确保即使NuGet包以某种方式引入到这样的应用程序项目中,通过NuGet引入的任何.NET标准实现库都会从生成中删除。因此,如果您引用在.NET Core 1.0发布时生成的.NET标准1.0 NuGet包,则所有它的NuGet依赖项被删除,您可以使用构建工具附带的支持库

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

发表评论