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

我一直在讨论 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.)

我的项目只导入(使用)一些库,我没有手动添加;即他们都是“随.NET标准附带”的图书馆.这些库是:

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

问题是,我决定让我的项目成为.NET Standard,因为我希望它能够跨.NET Framework和.NET Core应用程序无缝地工作.我认为标准的重点是设置最低级别的兼容性.通过扩展,我想我曾(或许是错误地)假设像System.Console这样的库可以在Core或Framework中自动使用.

当我在同一个解决方案中测试我的Standard项目作为Framework和Core项目中的依赖项时,我没有注意到这样的事情,所以我怀疑这可能是一个NuGet的事情.

这里到底发生了什么?如何在没有大量依赖项的情况下在NuGet上提供我的.NET标准库?

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

你没有做错任何事,预计会发生这种情况.如果您只想将自己的DLL添加到新的.NET Framework项目中,则必须为您的库定位.NET Standard 2.0,等待本机支持API和汇编版本的.NET Framework版本 – 这将是为4.7.2(虽然.NET Framework 4.7.1支持所有API,但有一些程序集的版本化存在错误,因此工具(VS 2017 15.5)将添加其他程序集来修复它).

您所看到的是.NET Standard的构建方式以及对支持的框架的支持的副作用.根据您定位的.NET Standard版本和用于引用库包的工具,这也有所不同.

在.NET标准中< 2.0,您引用NETStandard.Library元数据包,后者又引用其他(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承诺的一部分). 在.NET Framework上,这些库(有一些例外,如System.Net.Http)没有做太多 – 它们只是转发到系统程序集.例如,“contract”定义System.Object是在System.Runtime.dll程序集中定义的.因此,您在.NET Framework应用程序中最终得到的System.Runtime.dll文件包含一个System.Runtime.dll,其中包含转发到.NET Framework的mscorlib.dll类型. .NET Core已经包含一个不同的System.Runtime.dll,它为该平台执行不同的操作.这种机制允许单个DLL文件在两个平台上工作,因为这些类型转发和其他实现确保在两个实现上工作的相同“契约”(类型程序集程序集版本). .NET Standard 2.0旨在减少必需的包和DLL的数量,并且每当发布新的.NET Core版本时,都要删除对.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 Standard 2.0以及.NET Standard 1.5完成的,因为.NET Framework 4.6.1通过这些类型的DLL文件追溯性地与.NET Standard 2.0(先前为1.4)兼容.相同的工具还确保即使NuGet包以某种方式引入到这样的应用程序项目中,从构建中删除通过NuGet引入的任何.NET标准实现库.因此,如果您引用.NET Core 1.0发布时构建的.NET Standard 1.0 NuGet包,则会修剪其所有NuGet依赖项,并获得构建工具附带的支持库. 想法是.NET Framework 4.7.1将包含所有必需的程序集“inbox”,以便netstandard.dll,System.Runtime.dll等是.NET Framework的一部分,任何.NET Standard 1.0-2.0 DLL文件都会“只是工作”,问题是这些“收件箱”DLL文件的某些程序集的版本号太低,因此库无法加载 – 这是通过再次更改工具以包含具有更高版本号的DLL文件作为支持库来解决的然后转发到“收件箱”.NET Framework程序集.计划在.NET Framework 4.7.2中修复此问题.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


什么是设计模式一套被反复使用、多数人知晓的、经过分类编目的、代码 设计经验 的总结;使用设计模式是为了 可重用 代码、让代码 更容易 被他人理解、保证代码 可靠性;设计模式使代码编制  真正工程化;设计模式使软件工程的 基石脉络, 如同大厦的结构一样;并不直接用来完成代码的编写,而是 描述 在各种不同情况下,要怎么解决问题的一种方案;能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免引
单一职责原则定义(Single Responsibility Principle,SRP)一个对象应该只包含 单一的职责,并且该职责被完整地封装在一个类中。Every  Object should have  a single responsibility, and that responsibility should be entirely encapsulated by t
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强烈推荐。原文截图*************************************************************************************************************************原文文本************
适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,它是针对软件开发中经常遇到的一些设计问题,总结出来的一套通用的解决方案。
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
迭代器模式提供了一种方法,用于遍历集合对象中的元素,而又不暴露其内部的细节。
外观模式又叫门面模式,它提供了一个统一的(高层)接口,用来访问子系统中的一群接口,使得子系统更容易使用。
单例模式(Singleton Design Pattern)保证一个类只能有一个实例,并提供一个全局访问点。
组合模式可以将对象组合成树形结构来表示“整体-部分”的层次结构,使得客户可以用一致的方式处理个别对象和对象组合。
装饰者模式能够更灵活的,动态的给对象添加其它功能,而不需要修改任何现有的底层代码。
观察者模式(Observer Design Pattern)定义了对象之间的一对多依赖,当对象状态改变的时候,所有依赖者都会自动收到通知。
代理模式为对象提供一个代理,来控制对该对象的访问。代理模式在不改变原始类代码的情况下,通过引入代理类来给原始类附加功能。
工厂模式(Factory Design Pattern)可细分为三种,分别是简单工厂,工厂方法和抽象工厂,它们都是为了更好的创建对象。
状态模式允许对象在内部状态改变时,改变它的行为,对象看起来好像改变了它的类。
命令模式将请求封装为对象,能够支持请求的排队执行、记录日志、撤销等功能。
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 基本介绍 **意图:**在不破坏封装性的前提下,捕获一个对象的内部状态,并在该
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为
享元模式(Flyweight Pattern)(轻量级)(共享元素)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结