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

包,元包与框架

本文翻译自 Packages, Metapackages and Frameworks。

.Net Core 是一种由 NuGet 包组成的平台。一些产品体验受益于代码包的细粒度定义,而另一些受益于粗粒度的定义,这两种定义都是有用的,不能绝对地说哪个好与不好。因此,为了适应这两种区别,一款好的产品应该可以被拆分成一组一组的细粒度的代码包,这些包之间相互独立,单个代码包的正式的名字叫做“元包”(metapackage)。

每个.Net Core 包都支持运行于多种 .Net 运行时中,这些运行时被称为 “框架”(framework)。其中有的框架是传统框架,例如 net46;而另一些则是新的框架,可以认为它们是“基于包的框架”,这种是框架的另外一种新的定义模型。这些基于包的框架整个都是由包组成的,它们自身也被定义成包,这就在框架与包之间形成了一种比较密切的关系。

.Net Core被分割成为一组包,它们提供了基元类型,以及更高层的数据类型,应用组合类型,以及公共的类库。每一个包都代表着单独的同名程序集,例如,System.Runtime 这个包,就包含了 System.Runtime.dll 这个程序集。

把这些包定义成为细粒度的结构风格,有以下好处:

  • 细粒度的包可以在它自己的开发周期内交付,只需要完成仅对相关的其他有限的包进行测试即可。

  • 细粒度的包可以提供不同的OS与CPU支持。

  • 细粒度的包可以单独依赖于某一个类库。

  • 应用可以变得更小,因为没有引用的包不会变成最终发布的一部分。

上述好处仅适用于某些特定的场合。比如,Net Core 的所有包会在同一个发布周期内提供对同一个平台的支持,在这种情况下,补丁与更新会以小的单独包的形式发布。由于这种小范围的变化,补丁的验证与相关工作,都可以限制到单个平台与类库的需求范围中,这样一来,就可以把工作最小化。

以下是 基于 NuGet 库的 .Net Core 包清单:

  • Sytem.Runtime - 最基础的 .Net Core 包,包含 Object,String,Array, Action 与 IList<T>。

  • System.Collections - 一组基元泛型集合,包含 List<T> 与 Dictionary<K,V>.

  • System.Net.Http - 一组用于 HTTP 网络通信的类型,包含 HttpClient 与 HttpResponseMessage。

  • System.IO.FileSystem - 一组用于读写本地或者网络磁盘存储的类型,包含了 File 与 Dictory 类。

  • System.Linq - 一组对象查询类型,包含了 Enumerable 与 ILookup<TKey, TElement> .

  • System.Reflection - 一组用于类型加载,检查与激活的类型,包含 Assembly, TypeInfo, 与 MethodInfo

包引用在 project.json 文件中定义,在下面的例子中,使用了 System.Runtime 包:

{
  "dependencies" : {
     "System.Runtime" "4.1.0"
   },
   "frameworks" : {
     "netstandard1.5" : {}
   }
}   

在大部分情况下,你可能不需要直接引用底层的 .Net Core 包,因为引用的包太多了会让你抓狂。所以你只需要引用元包。

元包

元包就是一个 NuGet 包,方便地描述了一组意义相关的包。开发团队利用依赖关系来描述一组包,他们通过这一组包来描述一个框架(framework),然后有选择地发布出去。

引用一个元包,这个操作,实际上添加了对元包中每一个独立包的引用依赖,这意味着这些包中所有的类库(refs 或者 libs)都会在智能感知(IntelliSense)中可用,同时也会发布(lib目录)到你的应用中。

注意: lib 与 ref 指的是 NuGet 包中的相应的文件夹, ref 目录描述的是以元程序集表示的公共API包,lib 目录 包含了这个公共API的在不同框架下的实现。

使用元包有以下好处:

  • 在引用大量细粒度包方面,提供了一种方便的用户体验。

  • 定义了一组经过充分测试与工作良好的包(包括指定的各种版本)。

.Net 标准类库元包:

  • NETStandard.Library - 描述了“.Net 标准类库”的一部分。所有的 .Net 实现(例如, .Net Framework, .Net Core, Mono)都支持 .Net 标准类库,这就是 'netstandard' 框架。

以下是 .Net Core 元包:

  • Microsoft.NETCore.App - 描述了 .Net Core 发行版本的部分类库,也就是 .NETCoreApp 框架。它依赖于NETStandard.Library 这个更小的元包。

  • Microsoft.NETCore.Portable.Compatibility - 一组兼容代理,使基于 mscorlib 的 可移植类库(PCL) 得以运行在 .Net Core上。

元包的引用方法就像普通的 NuGet包一样,在 project.json 中定义。

在下面的例子中, 引用了 NETStandard.Library 这个元包,用来创建一个基于 .Net 运行时的可移植类库。

{
   "dependencies" : {
     "NETStandard.Library" "1.5.0"
   },
   "frameworks" : {
     "netstandard1.5" : {}
   }
}

  

在下面的例子中,引用了 Microsoft.NETCore.App 这个元包,用来创建应用或者是类库,运行于 .Net Core之上,并且充分使用 .Net Core 所有功能。它提供的访问范围,要比 NetStandard.Library 更大。

{
   "dependencies" : {
     "Microsoft.NETCore.App" "1.0.0"
   },
   "frameworks" : {
     "netcoreapp1.0" : {}
   }
}  

框架

每一个 .Net Core 包都支持一组框架,在框架文件夹中进行声明(就在前面所说的 lib 与 ref目录中)。框架描述了一组可用的API(以及潜在的其他特性),所以你可以在指定一个目标框架时得到这些功能。当新的API加入时,就会进入版本管理流程。

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

  • .NETFramework,版本 4.6

  • .NETStandard,版本 1.3

  • 6种Xamarin 平台 (如, xamarinios10)

很有必要对前两种框架进行对比,因为它们各自代表了一种不同的框架定义方式。

.NETFramework,Version=4.6 这个框架代表了在 .Net Framework 4.6 中可用的API,你可以根据这些API生产自己的类库,引用其中的程序集,并以NuGet包的方发布你的类库,发布后它们会位于lib文件夹下一个名为 net46 的文件夹中。这样,你的

类库就会被那些基于或者兼容 .Net Framework 4.6 的应用程序所使用。这是传统类库的工作方式。

而.NETStandard,Version=1.3这个框架是一个基于包的框架。那些以此框架为目标的包,定义并且实现的API,就组成了这个框架。

可见它们的区别:传统的框架是事先定义好的一个整体,而基于包的框架,则可以对不同的包自由组合。

基于包的框架

框架与包之间的关系是双向的。

首先是为一个给定的框架定义了一组API,如 netstandard1.3。以 netstandard1.3 为目标的包(或者兼容框架,如netstandard1.0)定义了哪些API是可以使用的,听起来像是循环定义,然而并不是。从 “基于包的”这个词本身的角度来讲,框架的API定义是来自于包的,框架本身并不定义任何API。

其次,是这个双向关系中的资产选择。包内部可以含有不同框架的资产,对于一组包或者元包的引用,框架需要决定它应选择哪些资产,例如,是 net46 还是 netstandard1.3。对于交叉资产来说,这个非常重要,例如,一个 net46 的资产可能并不会与 .Net Framework 4.0 或者 .Net Core 1.0 兼容。


你可以在上图中看到这种关系,API 选择 框架 作为目标,并且API定义了框架, 而框架用于资产选择,资产实现了API。

这里出现了一个有趣的问题:框架定义的结束之处,正是消费开始的地方。可以把框架看成是由 project.json 文件给出的功能定义,你所依赖的东西创建了实际上的框架,这个框架独立于那些已经发布出来的完整框架的依赖项。(译者注:可以这么理解,

框架的实际实现取决于你在 project.json 中引用的东西,可能你并不会引用所有的包,所以你所依赖的包是官方框架的全部包的一个子集。)

在.Net Core基础之上,基于包的框架主要有两个:

  • netstandard

  • netcoreapp

.NET Standard

.NET 标准框架(netstandard)意指基于 .Net 标准类库所定义与构建的API。如果你所构建的类库将会用于多种运行平台,应该以基于netstandard进行构建,这样类库就会支持任何一种 兼容 .Net 标准的运行时,比如 .Net Core, .Net Framework以及 Mono/Xamarin。这些运行时中的每一处都支持一种或几种 .Net 标准,至于到底支持哪个版本,则取决于具体实现。

元包 NETStandard.Library 的目标框架是 netstandard。要以 netstandard 为目标框架,最常见的方法是引用此元包。它定义与提供了约40个.Net类库,并与.Net 标准类库所定义的API相关联。你可以引用基于 netstandard 开发的第三方包来使用第三方API。

一个给定的 NETStandard.Library 版本,总是与 netstandard 所公开的最高版本相匹配。 project.json 文件中对于框架的引用,主要是用来从此框架中选择正确的资产。因此,假如定义了 netstandard1.5,就需要 其中的dll资产,而不是 netstandard1.4,或者 net46。

{
  "dependencies" : {
    "NETStandard.Library" "1.5.0"
  },
  "frameworks" : {
    "netstandard1.5" : {}
  }
}

  

这个 project.json 文件中所引用的 框架与元包 并不需要严格匹配,例如下面的 project.json 也是正确的:

{
  "dependencies" : {
    "NETStandard.Library" "1.5.0"
  },
  "frameworks" : {
    "netstandard1.3" : {}
  }
}   

把构建目标设置为 netstandard1.3 却使用 NETStandard.Library 的 1.5 版本,似乎有点奇怪。然而这是一个合法的用例,因为元包支持更老的 netstandard 版本。可能恰好 你使用了 1.5.0 的元包版本来开发你所有的类库,然后运行于多种版本的 netstandard,在这种情况下,你只需要重新加载 NETStandard.Library 1.5.0 即可,并不需要加载早期版本。

反之则并不成立:把 netstandard1.5 作为运行目标,却使用 NETStandard.Library 的 1.3.0 版本来开发你的类库:你不能够把更高版本的框架作为开发目标,却使用更低版本的元包。元包资产的版本管理机制,与框架的最高版本的定义相匹配。借助于版本管理机制,NETStandard.Library 的第一个版本是 v1.5.0,它包含了 netstandard1.5 的资产。而上面例子中的 v1.3.0 版本,只是为了举例方便,实际上并不存在。

译者注:这一段的各种名词相互绕来绕去,会把人绕晕。举个例子就明白了:因为类库总是向下兼容的,1.5 的实现必然包含了1.3的所有定义,1.5 版本的元包,是可以运行于 1.3 版本的框架之上。

然而这与我们的直觉经验不符,因此作者说看起来很奇怪,因为你在 Win7 上开发的程序(依赖高版本元包),很可能不支持运行在 XP 系统上(低版本框架)。

但是为什么在神奇的 .Net Core 的世界中,这个现象就发生了呢?

这是由 .Net Core 的版本管理机制所决定的。文中并没有给出来具体的解释。关于版本管理,有另外一篇文章会介绍,稍后翻译。

.NET Core Application

.NET Core Application 框架(netcoreapp) 意为: 包与相关的API是 基于.Net Core 特定发布版本以及它所提供的控制台程序模型。.Net Core应用程序必须使用这个框架,因为必须要使用其中的控制台程序模型。同时只运行于 .Net Core 平台的类库也应使用这个模型。使用这框架以后,应用程序(exe)与类库(dll)将只能够运行于.Net Core平台上。(老外好啰嗦啊) 元包 Microsoft.NETCore.App 的目标框架是 netcoreapp 。此元包提供了约 60 个类库,其中大约 40 个是由 NETStandard.Library 提供的,另外20个是由 Microsoft.NETCore.App 自己实现的(addition)。如果你开发的类库的目标框架是 netcoreapp 或其兼容框架(如netstandard),则可以使用 Microsoft.NETCore.App 的这些20个额外类库(addition),来调用这些额外的API。

译注:addition,是指由 Microsoft.NETCore.App 在 NETStandard.Library 基础之上的额外实现,约20个类库。在从传统 Framework迁移过来的代码中,如果你使用了 NETStandard.Library ,可能会出现不识别类或者方法的情况,很有可能是因为这些不识别的部分实现在这20个addition中,改为引用 Microsoft.NETCore.App 可能会解决问题。

由 Microsoft.NETCore.App 额外实现的大部分类库,也可以运行于 其他的 netstandard 框架,如果这些框架满足了它们所依赖的类库的运行环境的话。这意味着 运行于 netstandard 框架的类库也引用这些额外包作为依赖项。

译注:这段话也比较晦涩,再举例子说明。例如 Microsoft.NETCore.App 1.5 (简称App1.5)是 在 NETStandard.Library 1.5 (简称Lib1.5)之上实现了额外20个包(Add20),即 App1.5 = Lib1.5 + Add20。 前面说 Lib1.5 可以运行于框架 netstandard 1.5(简称 Std1.5),以及 Std1.3 之上,如果这个 Add20 也可以运行于 Lib1.3 的话,那么就可以得到 App1.5 也可以运行于 Lib1.3。

原文地址:http://www.cnblogs.com/liuweizzuie/p/5827030.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328616.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试项目 java-服务端2 18h58

idea2017对mybatis plugin支持不是很好 标准的meaven项目用谁都一样 archetype是官网提供的模板项目 .gitignore文件非常的重要配置 Meven的pom文件 项目的包结构 Mybatis三剑客

Java剪切板操作大全

转载自 Java剪切板操作大全1. 概述提起剪切板&#xff0c;一般都是在桌面系统或工具中使用。目前&#xff0c;操作Java剪切板有两种形式&#xff0c;这也对应着两种不同的技术Swing和JavaFX。而剪切板有可以分为系统剪切板和自定义剪切板。顾名思义&#xff0c;系统剪切板可以…

君威u0073故障码解决_顽疾修复过程,君威没倒挡的变速箱故障就是这样修好

君威没倒挡的变速箱故障表现&#xff1a;开了18万公里的君威有没有倒挡的故障发生。每当这时&#xff0c;要重新启动能恢复。但是&#xff0c;出现的没倒挡的次数逐渐增多。没检查出故障码。顽疾修复过程&#xff0c;君威没倒挡的变速箱故障就是这样修好&#xff1a;检查君威变…

idea创建标准的meaven项目

若没有jdk 则这样配置 就是下拉框默认没有jdk1.7 初始化完成了

新闻发布项目——接口类(categoryTBDao)

package bdqn.newsMange.Dao;import java.util.List;import bdqn.newsMange.entity.categoryTB;/*** 新闻类别的接口* author Administrator**/ public interface categoryTBDao {//查询所有的类别public List<categoryTB> getCategoryTBAll();//添加新闻类别public int …

controller属于哪一层_别急着换5G,4G手机同样值得考虑!哪几款安卓手机称得上4G机皇?...

今年已经进入了5G手机大战&#xff0c;目前有不少厂商都推出了自家的5G旗舰。虽说5G是以后的主流&#xff0c;但目前入手5G手机还为时尚早&#xff0c;毕竟距离5G全面普及还有至少2年时间&#xff0c;5G的套餐费用也高出许多。当前一些4G旗舰机型价格下降幅度不小&#xff0c;马…

基于.NET SingalR,LayIM2.0实现的web聊天室

LayIM官网 http://www.layui.com/doc/layim.html 博客教程&#xff1a;http://www.cnblogs.com/panzi/p/5767095.html 项目说明&#xff1a;基于.NET SingalR,LayIM2.0实现的web聊天室&#xff0c;功能如下&#xff1a; 注册登录 好友聊天&#xff0c;发送图片、文件 群组聊天&…

java验证身份证号码是否有效源代码

转载自 java验证身份证号码是否有效源代码1、描述 用java语言判断身份证号码是否有效&#xff0c;地区码、出身年月、校验码等验证算法2、源代码package test; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import …

idea初始化git 初始化git仓库

git status 查看变化 主干发布 分支开发 git 初始化 和git的分支完成了

互换性与技术测量教材pdf_【检验】临床生物化学检验技术(第6版)人民卫生出版社【电子教材PDF】【人卫教材电子版】...

内容简介为了顺应医学教育综合改革的发展趋势&#xff0c;推动我国医学检验技术专业的发展和学科建设&#xff0c;针对四年制医学检验技术专业人才的培养目标和培养模式&#xff0c;贯彻四年制教育思想&#xff0c;体现适合四年制教学需求的课程体系建设&#xff0c;教育部高等…

MyEclipse生成Javadoc帮助文档

转载自 MyEclipse生成Javadoc帮助文档 Javadoc是Sun公司提供的一个技术&#xff0c;它从程序源代码中抽取类、方法、成员等注释形成一个和源代码配套的API帮助文档。也就是说&#xff0c;只要在编写程序时以一套特定的标签作注释&#xff0c;在程序编写完成后&#xff0c;通过…

Redis集群~StackExchange.redis连接Sentinel服务器并订阅相关事件

对于redis-sentinel我在之前的文章中Redis集群~StackExchange.redis连接Twemproxy代理服务器 已经说过&#xff0c;它是一个仲裁者&#xff0c;当主master挂了后&#xff0c;它将在所有slave服务器中进行选举&#xff0c;选举的原则当然可以看它的官方文章&#xff0c;这与我们…

新闻发布项目——接口类(BaseDao)

package bdqn.newsMange.Dao; /*** 公共类* author Administrator**/ import java.sql.*; import java.util.List; public class BaseDao {Connection connnull;PreparedStatement psnull;ResultSet rsnull;public Connection getConnection() throws ClassNotFoundException, …

docker容器的标准使用过程_phpStorm中使用xdebug工具调试docker容器中的程序

最近使用了docker容器来构建项目&#xff0c;这种方式虽然极大的加快了构建的项目速度&#xff0c;但是也会对之前的本地开发带来一些挑战&#xff0c;比如今天讲到的调试程序&#xff0c;大家对于xdebug一定不会陌生&#xff0c;但是如果php-fpm放到了容器里面&#xff0c;又该…

Meaven的pom文件配置

archtype自动生成的 直接复制讲解一下好了 https://search.maven.org/ maven中央仓库 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.or…

Google 的开源方法论

没有开源&#xff0c;Google 不会有今天的成功。在本周举行的北美 Linux 大会上&#xff0c;Google 工程师 Merlin 从一个第三方视角概括了 Google 是如何使用和为开源做出贡献。自 2002 年以来&#xff0c;Marc Merlin 一直担任 Google 的工程师&#xff0c;期间做过许多开源项…

修改Eclipse/MyEclipse项目的默认编码

转载自 修改Eclipse/MyEclipse项目的默认编码最近遇到问题&#xff0c;在myeclipse新建或导入项目后&#xff0c;有些文件中文显示乱码&#xff0c;每次都要在项目property中修改其编码&#xff0c;所以想到一次性解决所有编码问题&#xff0c;让项目新建或导入之后自动是utf…

hashmap存多少条数据_干货 | 面试官想问的HashMap,都在这一篇里面了!

来源公众号&#xff1a;非科班的科班本文思维导图HashMap简介HashMap 是很常用的一种集合框架&#xff0c;其底层实现方式在 JDK 1.7和 JDK 1.8中却有很大区别。HashMap 是用来存储数据的&#xff0c;它底层在JDK 1.7是数组链表实现的&#xff0c;而JDK 1.8是使用数组链表红黑树…

StackExchange.Redis客户端读写主从配置,以及哨兵配置

今天简单分享一下StackExchange.Redis客户端中配置主从分离以及哨兵的配置。 关于哨兵如果有不了解的朋友&#xff0c;可以看我之前的一篇分享&#xff0c;当然主从复制文章也可以找到。http://www.cnblogs.com/tdws/tag/NoSql/ 为什么要有这篇分享呢&#xff0c;是因为我之前也…

Windows7下如何设置MyEclipse2014字体大小

转载自 Windows7下如何设置MyEclipse2014字体大小Java开发工具MyEclipse2014&#xff0c;安装完毕后发现字体过小&#xff0c;并且对眼睛不好&#xff0c;该如何设置这个开发工具里整体字体大小。设置MyEclipse字体大小&#xff0c;具体实现看下面详细描述双击“MyEclipse Pr…