Tom*_*ght 48 .net nuget .net-standard
我一直在讨论.NET Standard项目和NuGet.我有一个工作项目并已将其上传到NuGet.org.我的项目面向.NET Standard 1.3,它应该支持 .NET Framework 4.6和.NET Core 1.0.
但是当我尝试将我的项目(通过NuGet)添加到一个新的.NET Framework 4.6项目时,依赖关系解析为47个包!它们都是系统库,似乎是Microsoft.NETCore.Platforms或NETStandard.Library 1.6.1的依赖项.(完整PM输出的要点.)
我的项目只导入using了几个库,其中没有一个是我手工添加的; 即它们都是"随.NET标准附带"的库.这些库是:
问题是,我决定让我的项目成为.NET Standard,因为我希望它能够跨.NET Framework和.NET Core应用程序无缝地工作.我认为标准的重点是设置最低级别的兼容性.通过扩展,我想我曾(或许是错误地)假设像System.Console这样的库可以在Core或Framework中自动使用.
当我在同一个解决方案中测试我的Standard项目作为Framework和Core项目中的依赖项时,我没有注意到这样的事情,所以我怀疑这可能是一个NuGet的事情.
这里到底发生了什么?如何在没有大量依赖项的情况下在NuGet上提供我的.NET标准库?
这是我指定我的NuGet包的方式有问题吗?或者我从根本上误解了什么?
Mar*_*ich 56
你没有做错任何事,预计会发生这种情况.如果您只想将自己的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 Standard <2.0中,您引用了NETStandard.Library元包,后者又引用了additional(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)没有做太多 - 它们只是转发到系统程序集.因此,例如,"契约"定义了System.Object在System.Runtime.dll程序集中定义的.因此,System.Runtime.dll您在.NET Framework应用程序中最终得到的文件包含一个System.Runtime.dll包含转发到.NET Framework的类型mscorlib.dll..NET Core已经包含了一个与System.Runtime.dll该平台不同的东西.这种机制允许单个DLL文件在两个平台上工作,因为这些类型转发和其他实现确保在两个实现上工作的相同"契约"(类型+程序集+汇编版本).
.NET Standard 2.0旨在减少必需的包和DLL的数量,并且还可以NETStandard.Library在发布新的.NET Core版本时删除需要更新的内容.
因此,对于.NET Standard 2.0和.NET Core 2.0,该NETStandard.Library程序包仅将用于编译代码的引用程序集引入项目,但生成的NuGet程序包不再依赖于此程序包.因此,当您创建一个面向.NET Standard 2.0并发布它的库时,它将没有NuGet依赖项(除非您添加其他的).
在使用.NET标准库时,"支持库"引入的逻辑被移动到构建期间使用的工具.因此,当包含对a的引用的库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框架4.7.1将包含所有必需的组件"收件箱",使一个netstandard.dll,System.Runtime.dll等是.NET Framework和任何.NET标准1.0-2.0 DLL文件将"只是工作"的一部分,问题是这些"收件箱"DLL文件的某些程序集的版本号太低,因此库无法加载 - 这是通过再次更改工具以包含具有更高版本号的DLL文件作为支持库来修复的,而这些文件又转发到"收件箱" ".NET Framework程序集.计划在.NET Framework 4.7.2中修复此问题.
我也碰到了这个问题。您在评论中链接到Martin Ullrich的答案的博客文章使我找到了一个对我有用的解决方案:使用NuGet多目标。通过更改:
<TargetFramework>netstandard1.0</TargetFramework>
Run Code Online (Sandbox Code Playgroud)
至
<TargetFrameworks>netstandard1.0;netstandard2.0;net45</TargetFrameworks>
Run Code Online (Sandbox Code Playgroud)
在项目.csproj文件中。这将导致为每个目标框架分别构建项目,并且生成的NuGet包仅取决于NETStandard.Libraryfor netstandard1.0。由于NuGet选择net45任何完整的.NET Framework版本的二进制文件,因此可以避免安装软件包时不必要的依赖关系。
| 归档时间: |
|
| 查看次数: |
5316 次 |
| 最近记录: |