本文为翻译文章,原文:Packages, Metapackages and Frameworks

.NET Core是一个由NuGet包组成的平台。一些产品受益于细粒度包的定义,也有一些受益于粗粒度包的定义。为了适应这种二重性,.NET Core平台被分为一组细粒度的包(package)以及一些被称为元包(metapackage)的较粗粒度的包。

每一个.NET Core包支持多个.NET运行时,它们代表着不同的框架。这些框架既包括传统的.NET Framework(如net4.6),也包含基于包的新框架,这些新框架建立了定义框架的新模型。这些基于包的框架完全由包定义而成,包与框架之间形成较强的关联关系。

.NET Core由一组包构成,这些包提供了基元类型、高级数据类型、应用程序组成类型和一些常见的实用工具。每一个包表示一个和包同名的程序集,如, System.Runtime包中含有System.Runtime.dll程序集。

定义细粒度的包有如下好处:

  • 细粒度的包在开发、测试过程中与其它包的关联有限

  • 细粒度的包可以提供对不同操作系统和CPU的支持

  • 细粒度的包可以只依赖某个特定的库

  • 在发布应用时,未被引用的包不会成为应用的一部分,因此应用程序会有更小的体积

有些细粒度包的优点只会在特定场景中表现出来。如,通常.NET Core 的所有包会在同一计划内提供对同一平台的支持。这种情况下,补丁会以小的单个更新包的形式发布和安装。由于这种小范围的变化,验证补丁是否可用所花费的时间,可以限制到对单个库的需求中。

下面列出了.NET Core平台上的一些关键NuGet包:

通常,与逐个添加项目所需要的包相比,使用元包的方式来添加项目依赖更加容易,因为元包是一组常用包的集合。当你需要某个单独的包时,你可以使用下面例子中添加对System.Runtime引用的方式来添加对它的引用。

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Runtime" Version="4.3.0" />
</ItemGroup>
</Project>

元包

元包是一个NuGet包约定,用于描述一组放在一起有意义的包。 这些包是通过依赖项来被描述的。可以通过为这组包指定一个框架来建立一个框架(这话拗口,原文:They can optionally establish a framework for this set of packages by specifying a framework.)。

以前版本的.NET Core工具(project.json和基于csproj的工具)在默认情况下会指定一个框架和元包 。不过,现在,元包被目标框架隐式引用,这样一来每个元包都和目标框架关联在一起。例如,netstandard1.6框架引用了NetStandard.Library 1.6.0元包。类似的,netcoreapp1.1框架引用了Microsoft.NETCore.App 1,1.0元包。更过信息,参考.NET Core SDK中元包的隐式引用

指定一个框架会隐式实现对元包引用,同时也会添加对元包依赖项的引用。这样,元包中的所有类库都能够被IDE智能感知,也可以被打包到你的应用中。

使用元包有以下好处:

  • 在引用大量细粒度包时有更好的用户体验

  • 定义了一组经过测试且运行良好的包(包括指定的各种版本)

.NET 标准库元包(.NET Standard Library metapackage):

  • NETStandard.Library - 表示.NET标准类库的一部分。所有的.NET 实现(如,.NET Framework、.NET Core 和 Mono)都支持.NET 标准类库。NETStandard.Library用于建立netstandard框架。

.NET Core核心元包有:

框架

每个.NET Core包都支持多个运行时框架。这些框架描述一组可用于你所指定的框架的API(和一些其它特征)。当加入新的API时,这些框架的版本号也会发生相应的变化。

例如, System.IO.FileSystem 支持以下框架:

  • .NETFramework,Version=4.6
  • .NETStandard,Version=1.3
  • 6 Xamarin platforms (如, xamarinios10)

这些运行时框架使用不同的方式进行框架的定义,对比学习前两个框架会大有裨益。

.NETFramework,Version=4.6框架表示可用于.NET Framework 4.6之上的API。

我们可以编写基于.NET Framework 4.6引用程序集的库,并以NuGet 包的方式在 net46 lib 文件夹中发布这些库。这些库可用于那些基于或兼容.NET Framework 4.6的应用。这是所有框架的传统工作方式。

.NETStandard,Version=1.3是一个基于包的框架。它依靠包来定义目标框架以及公开该框架的API。

基于包的框架

包与框架之间是双向关系。首先为一个给定框架定义可用的API,如netstandard1.3。用于netstandard1.3框架(或兼容框架,如netstandard1.0)的软件包定义该框架上可用的API。这看起来像是循环定义,但不是。基于包的框架上的API由包来定义,框架本身并不定义任何API。

其次,是这种双向关系中的第二部分,资产选择(asset selection)。包可以包含用于多框架的资产。对于一组包或者元包的引用,框架需要决定选择哪种资产,如net46netstandard1.3。选择正确的资产是很重要的。如,一个net46资产可能不兼容.NET Framework 4.0 或 .NET Core 1.0

 

上图描述了这种双向关系。API指定并定义框架。框架选择资产。资产提供具体的API实现。

.NET Core平台上使用的两个主要的基于包的框架是:

  • netstandard

  • netcoreapp

.NET 标准

.NET标准(目标框架名:netstandard)框架是指基于.NET标准库(.NET Standard Library)而定义和创建的API。这些库计划支持以.NET 标准框架为目标框架的多个运行时。它们支持任何与.NET标准(.NET Standard )兼容的运行时,如.NET Core、.NET Framework和Mono/Xamarin(下面附上一张图作为补充)。每个运行时都支持一组.NET Standard版本,具体取决于它们所要实现的API。

 

标准框架隐式引用NETStandard.Library元包。如,下面的MSBuild项目文件显示了当前项目的目标框架是netstandard1.6,这个框架引用.NET Standard Library version 1.6元包。

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
</Project>

但是,框架和项目文件中所引用的元包无需一一对应,你可以在项目文件中使用<NetStandardImplicitPackageVersion>来制定一个版本号低于元包版本号的框架。如,下面的配置框文件是有效的。

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
</PropertyGroup>
<ItemGroup>
<NetStandardImplicitPackageVersion Include="NetStandardLibrary" Version="1.6.0" />
</ItemGroup>
</Project>

netstandard1.3框架使用NETStandard.Library 1.6.0可能看起来比较奇怪。但这种使用情况是合法的,因为元包向后兼容低版本的netstandard。若你已经将1.6.0版本的元包并将其应用到自己的面向多个netstandard版本的库中。通过这种向后兼容的方式,你只需还原(restore)NETStandard.Library1.6.0而无需关注更早的版本。

与此相反,netstandard1.6引用NETStandard.Library 1.3.0是不被允许的,因为低版本的元包不会公开任何构建高版本框架的资产。元包资产的版本控制使得元包和它们所描述的框架的最高版本相匹配。借助版本控制,NETStandard.Library的第一个版本是1.6.0,它包含netstandard1.6的资产。上述例子中的1.3.0版本只是为了举例需要,事实上它并不存在。

.NET Core 应用

.NET Core 应用(目标框架:netcoreapp)框架表示.NET Core 发行版和它提供的控制台应用程序模型附带的包和相关API。.NET Core应用必须使用该框架,因为它基于的控制台应用模型的库仅仅运行于.NET Core框架上。使用这个框架可以限制应用和库只运行于.NET Core之上。

Microsoft.NETCore.App元包的目标框架是netcoreapp。它支持对约60个库的访问,其中约40个由NETStandard.Library提供, 还有约20个其它(标准库以外的)附加库。你可以引用基于或兼容netcoreapp,如netstandard的附加库,以获取对附加库API的访问。

大多数由Microsoft.NETCore.App提供的附加库,如果这些库可以很好的依赖其它的netstandard库的话,它们也可用于netstandard。这意味着netstandard libraries可以添加对这些包的引用。

结语

由于水平有限,翻译内容难免有错误和不足之处,希望大家提出改进意见。文章最后是自己建立.NET Core控制台程序的引用包截图和项目配置文件,大家可以作为辅助理解文章内容的补充材料。

项目包引用

packages.PNG

项目文件

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Collections.NonGeneric" Version="4.3.0" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.3.0" />
</ItemGroup>
</Project>

版权声明

本文为作者原创,版权归作者雪飞鸿所有。 转载必须保留文章的完整性,且在页面明显位置处标明原文链接

如有问题, 请发送邮件和作者联系。

.NET Core中的包、元包与框架的更多相关文章

  1. .net core中的那些常用的日志框架(NLog篇)

    前言 咱们上回讲到,.net core中内置的Logging日志框架的使用,以及浅显的讲解,接下来,给大家介绍一个第三方日志框架(NLog). NLog简介 NLog是适用于各种.NET平台(包括.N ...

  2. .net core中的那些常用的日志框架(Serilog篇)

    前言 上文说到Nlog日志框架,感觉它功能已经很强大,今天给大家介绍一个很不错的日志框架Serilog,根据我的了解,感觉它最大的优势是,结构化日志,它输出的日志是Json的格式,如果你使用的是Mon ...

  3. .net core中的那些常用的日志框架(Logging篇)

    前言 日志,在我们每个项目中是必不可少的,它不仅能在调试的时候测试数据,而且在项目上线,也是我们排查错误的得力助手,那我就能谈谈,用的多的几个日志框架吧!如果有不对的地方,欢迎来指教错误,谢谢! As ...

  4. 在.NET Core中使用Exceptionless分布式日志收集框架

    一.Exceptionless简介 Exceptionless 是一个开源的实时的日志收集框架,它可以应用在基于 ASP.NET,ASP.NET Core,Web Api,Web Forms,WPF, ...

  5. .Net Core 中的包、元包与框架(Packages, Metapackages and Frameworks)

    包,元包与框架 本文翻译自 Packages, Metapackages and Frameworks. .Net Core 是一种由 NuGet 包组成的平台.一些产品体验受益于代码包的细粒度定义, ...

  6. 大话DI依赖注入+IOC控制反转(二) 之 浅析.Net Core中的DI与IOC

      转发时请注明原创作者及地址,否则追究责任.原创:alunchen 在上一篇文章中,我们聊了很多关于定义的方面,比较孤燥,下面我们结合.Net Core聊一下依赖注入&控制反转. 三种对象生 ...

  7. .Net Core 学习笔记1——包、元包、框架

    .Net Core 是由NuGet包(package)组成的平台. 一起使用的多个包的集合:元包(Metapackage) package 包 (对应以前的程序集概念) Framework 框架 as ...

  8. 解决 .net core 中 nuget 包版本冲突问题

    今天在一个 asp.net core 项目中遇到了 nuget 包版本冲突的问题,错误信息如下: Version conflict detected for Microsoft.AspNet.WebA ...

  9. .NET Core中创建和使用NuGet包

    在.NET Core的项目中,如果我们要在项目中引用其它DLL文件,不应该直接在项目引用中添加DLL文件(虽然在.NET Core项目中也可以这么做),建议是去直接下载DLL文件所属的NuGet包.这 ...

随机推荐

  1. 集群环境下JSP中获取客户端IP地址的方法

    String ip = request.getHeader("X-Forwarded-For");if (ip == null || ip.length() == 0 || &qu ...

  2. 编写JQuery插件-2

    继续上一节的代码 (function(){ /* code */ })() 来我们介绍一下吧,首先定义一个匿名函数 fnction(){/* 这里放置代码 */} 然后用括号括起来, (fnction ...

  3. 使用HeartBeat实现高可用HA的配置过程详解

    一.写在前面 HA即(high available)高可用,又被叫做双机热备,用于关键性业务.简单理解就是,有2台机器 A 和 B,正常是 A 提供服务,B 待命闲置,当 A 宕机或服务宕掉,会切换至 ...

  4. java多线程四种实现模板

    假设一个项目拥有三块独立代码块,需要执行,什么时候用多线程? 这些代码块某些时候需要同时运行,彼此独立,那么需要用到多线程操作更快... 这里把模板放在这里,需要用的时候寻找合适的来选用. 总体分为两 ...

  5. java对获取的字节数组进行处理

    java对获取的字节数组bytes[]进行处理: 第一种,直接将该字节数组转换为字符串(部分): String content = ,); //从位置0开始获取2个字节 这样,对获取的数据报进行全部转 ...

  6. 【Javaweb】笔面试题 ---(1)

    Javaweb 面试题:理解才是最重要的,而不是原封不动的背下来 一.请简述doget和dopost它们的区别 1) get是从服务器上获取数据,post是向服务器传送数据. 2) 在客户端,Get方 ...

  7. CSS3的属性为什么要带前缀

    使用过CSS3属性的同学都知道,CSS3属性都需要带各浏览器的前缀,甚至到现在,依然还有很多属性需要带前缀.这是为什么呢? 我的理解是,浏览器厂商以前就一直在实施CSS3,但它还未成为真正的标准.为此 ...

  8. HTML5发展史

    2007年W3C(万维网联盟)立项HTML5,直至2014年10月底,这个长达八年的规范终于正式封稿. 在互联网的早期,对用户而言,能打开浏览器接入到互联网世界就是一个神奇的事情,但互联网发展到200 ...

  9. mac os x在PC上安装

    系统安装之前的准备工作及安装过程简介 前面我们已经提到,苹果电脑虽然已经采用了x86架构的Intel处理器,但其官方并不提供在非苹果电脑上安装Mac OS的支持.所以,要想在普通PC/笔记本电脑上安装 ...

  10. js拉起或下载app

    产品提了个需求,通过手机网页判断是否安装了自己公司app,如果安装了则拉起app,没有安装则跳转到下载页. 经过各种查阅资料尝试总结了一个还算可以的办法. 拉起app的原理就是js和原生统一好一个地址 ...