当前位置: 代码迷 >> C# >> 引见.NET Core
  详细解决方案

引见.NET Core

热度:504   发布时间:2016-04-28 08:29:29.0
介绍.NET Core

  在connect (),我们宣布.NET 核心将能完全释放,作为开放源码软件我也答应在.NET 核心跟更多的细节。在这篇文章,我将提供.NET 核心,我们如何去释放它,它涉及到.NET 框架,如何和这意味着跨平台和开放源代码发展概况。

回望 — — 激励.NET Core

第一次让我们回头来了解.NET 平台如何打包在过去。这有助于激励的一些决定和结果创建了.NET 核心的想法。

.NET — — 这一套的纵向市场

我们最初在 2002 年发运.NET 框架时只有一个单一的框架。不久之后,我们发布了.NET 框架精简版是适合更小的设备,专门为 Windows Mobile 足迹.NET 框架的一个子集。紧凑的框架是一个单独的代码库从.NET 框架。它包括整个垂直: 运行库、 框架和应用程序模型顶上的。

自那时以来,我们已经多次这个子集练习: Silverlight,Windows Phone 和大多数最近为 Windows 应用商店。这会产生碎片,因为.NET 平台并不是一个单一的实体,但一套平台,由不同的团队,拥有和保持独立。

当然,还有什么毛病提供专门的功能以满足特定的需要。但它成为一个问题,如果没有系统的方法和专业化发生在很小的在其他垂直的相应层没有顾及每一层。结果是一组只分享事实,他们开始从常见的代码库的 Api 的平台。随着时间的推移这将导致更多分歧除非显式 (且昂贵) 的措施采取收敛的 Api。

破碎的问题是什么?如果你只针对单个垂直然后真的没有任何问题。你提供了一个 API 集,就是优化您的垂直。只要你想要的目标水平,这是多个垂直产生了问题。现在,你必须有可用的 Api 的理由和拿出一种方法来产生你想要的目标的垂直跨工作的资产。

今天它是极为平常的事情有跨设备的应用程序: 那里是几乎总是运行在 web 服务器上,往往是行政的前端使用 Windows 桌面和一组暴露给消费者,可供多个设备的移动应用程序的后端。因此,它是关键以支持开发人员构建可以跨所有的.NET 垂直的组件。

可移植类库的诞生

最初,是代码的跨行业共享没有概念。没有可移植类库,没有共享的项目你基本上被困与创建多个项目,链接的文件和#if这使得针对多个垂直一个艰巨的任务。

在 Windows 8 周期中我们赶上了一项计划来处理这个问题。当我们设计的 Windows 应用商店配置文件我们引入了新的概念模型的子集在更好的方式: 合同。

原来,.NET 框架就被围绕假设作为一个单一的单位,部署了始终,所以保理业务并不关心。一切取决于核心大会是 mscorlib。Mscorlib.NET 框架提供的包含许多功能不能支持无处不在 (例如,远程处理和 Appdomain)。这迫使每个垂直子集平台的核心。这使它非常复杂工具让你的目标多个垂直类图书馆经验。

观念上的合同是提供构造良好的 API 表面积。合同是简单地反对编译的程序集。与常规程序集合同程序集是围绕适当保理业务设计的。我们深切关注这些依赖项之间的合同,他们只有一个单独的职责,而不是被抓包的 Api。独立合同版本和遵循正确的版本控制规则,如添加 Api 结果在较新版本的程序集。

我们用合同来跨所有纵向市场模型 API 集。垂直可以然后简单地选择他们想要支持的合同。一个重要方面是垂直必须支持合同,批发或根本没有。换句话说,他们不能子集的合同内容。

这允许推理关于垂直在程序集级别,而不是我们以前单个 API 级别的 API 差异。这一方面使我们能够提供可以针对多个行业,也被称为可移植类库的类图书馆经验。

统一与统一执行 API 形状

可以将可移植类库看作结合基于其 API 形状的不同.NET 垂直的经验。解决这个问题最迫切的需要,这是创建在不同.NET 垂直运行的库的能力。它还担任设计工具到驱动器收敛之间垂直,例如,Windows 8.1 和 Windows Phone 8.1 之间。

然而,我们仍然有不同的实现 — — 或叉 — —.NET 平台。那些实现由不同团队,版本独立,并有不同的运输车辆。这使得统一 API 形状不断面临的挑战: API 只是便携式时执行跨所有的垂直向前移动,但由于代码库的不同,是相当昂贵,因此总是服从 (稀土) 确定优先次序。即使我们可以做一个完美的工作,通过收敛 Api: 所有垂直都有不同的运输车辆,这意味着对生态系统的某些部分将总是落在后面。

更好的方法统一实现: 而不是只提供一个构造良好的看法,我们应该提供一个构造良好的实现。这将允许垂直简单分享相同的实现。收敛将不再是额外的;它被通过建设。当然,还有一些情况下我们可能需要多个实现的地方。文件 I/O,这需要使用不同的技术,基于环境是一个很好的例子。然而,它是要问每个团队拥有特定的组件,想想他们的 Api 跨所有纵向市场比试图追溯提供一致的 API 堆栈顶部的工作简单得多。这是因为可移植性不是一个什么东西你可以稍后提供。例如,我们的文件 Api 包括支持为 Windows 访问控制列表 (ACL),不能在所有环境中支持。Api 的设计必须考虑这问题,和,例如,在不支持 Acl 的平台上提供此功能在一个单独的程序集,可以省略。

全机的框架与本地应用程序框架

另一个有趣的挑战就是要与.NET 框架如何部署。

.NET 框架是一个机全框架。对它所做的任何更改会影响所有应用程序都以它的依赖项。有一个机器全框架是一个深思熟虑的决定,因为它解决了这些问题:

  1. 它允许集中服务
  2. 它减少了磁盘空间
  3. 允许共享应用程序之间的本机映像

但它也是需要付出代价。

其一,它复杂应用程序开发人员对最近公布的框架采取一个依赖项。你必须带上最新的操作系统依赖项或提供应用程序的安装程序能够安装.NET 框架时安装的应用程序。如果你是一个 web 开发者你可能甚至没有此选项因为 IT 部门告诉你允许你使用哪个版本。如果你是移动开发者你真的没有选择,但您的目标操作系统。

但即使你愿意通过提供安装程序,以便在.NET 框架安装链的麻烦,你可能会发现升级.NET 框架可以破坏其他应用程序。

坚持 — — 我们不说我们的升级高度兼容吗?我们都是。并且我们非常认真的兼容性。我们有为对.NET 框架所做的任何更改进行严格的审核。任何可能被重大更改为我们有专门的审查调查的影响。我们运行兼容实验室,在这里我们测试许多流行.NET 应用程序,以确保我们不回归他们。我们也有能力告诉应用程序编译的.NET 框架。这使我们能够保持与现有应用程序的兼容性,同时,选择到最终目标较新版本的.NET 框架为应用程序提供更好的行为。

不幸的是,我们还学甚至兼容的更改可以中断应用程序。让我举几个例子:

  • 将接口添加到现有的类型可以中断应用程序,因为它可能会干扰类型如何被序列化。

  • 以前并没有任何重载方法中添加重载可以打破从来没有处理发现超过一个方法的反射消费者。

  • 重命名一个内部类型可以中断应用程序,如果该类型名称通过 tostring () 方法浮出水面。

那些是都罕见的情况下,但当你有 18 亿机器兼容的 99.9%的客户群可以仍然意味着 180 万机受到影响。

更有趣的是,在许多情况下修复受影响的应用程序是相当琐碎的。但问题是,应用程序开发人员并不一定涉及中断发生时。让我们看看一个具体的例子。

您测试您的应用程序,.NET 框架 4 上,这是您与您的应用程序的安装。但一些第一天的您的客户安装另一个应用程序升级到.NET 框架 4.5 的机器。你不知道您的应用程序是破碎的直到该客户调用您的支持。在这一点上处理您的应用程序的兼容问题是软件的相当昂贵的因为你必须得到相应的源、 设置摄制机、 调试应用程序,进行必要的更改,他们融入发布分支,产生新版本,测试它,和终于发布更新为您的客户。

这与您决定您想要利用在较新版本的.NET 框架发布功能在哪里的情况形成对比。在这一点上在发展过程中,你已经准备好对您的应用程序进行更改。如果有一个轻微的兼容故障,你可以轻松地处理它作为功能工作的一部分。

由于这些问题,我们花一段时间来发布一个新版本的.NET 框架。更激烈的变化,更多的时间,我们需要烤它。这个结果在自相矛盾的情况,在那里我们测试版已经相当锁定了,我们几乎无法采取设计更改请求。

两年前,我们已经开始船上 NuGet 库。因为我们没有将这些库添加到.NET 框架我们将他们称为"带内"。带外库不患上我们只是讨论,因为它们是应用程序本地的问题。换句话说,库部署,如果他们是您的应用程序的一部分。

这很大程度解决了阻止您升级到较新版本的所有问题。你采取较新版本的能力只限制的能力,释放您的应用程序的更新版本。这也意味着你在控制哪个版本的图书馆正在利用特定的应用程序。升级完成而不会影响在同一台机器上运行的其他应用程序在单个应用程序的上下文中。

这使我们能够发布的更新,以更加灵活多样的方式。NuGet 还提供预览版本,让我们释放位尚未提交特定 API 或行为上的概念。这支持工作流,在那里我们可以提供你与我们最新的设计,以及 — — 如果你不喜欢它 — — 只是更改它。很好的例子,这是不变的集合。它有约九个月的试用期间。我们花了很多时间试图获得正确的设计之前我们发货的第一版本。不用说决赛设计 — — 感谢你提供 — — 的广泛反馈方式比初始版本要好。

输入.NET 核心

所有这些方面使我们重新思考和改变的造型向前的.NET 平台的方法。这导致在.NET 核心创作:

.NET 核心是可以用在各种各样的垂直缩放从触摸基于的设备的数据中心的模块化实现是可用作为开放源码和支持由微软 Windows、 Linux 和 Mac OSX 上。

让我走进的如何.NET 核心看起来像,它是如何解决问题我前面讨论的更多细节。

为.NET 本机和 ASP.NET 的统一的实施

当我们设计.NET 本机很显然我们不能使用.NET 框架为基础的框架类库。这是因为.NET 本机基本上合并与应用程序框架,然后再移除碎片,不需要由应用程序之前它生成的本机代码 (我大大简化这一过程在这里。有关更多详细信息,看看这深潜)。正如我刚才所说,.NET 框架执行不考虑使得它极具挑战性,链接器以减少多少框架获取编译成应用程序 — — 依赖封闭是太大。

ASP.NET 是 5 面临类似的挑战。尽管它不使用.NET 本机新的 ASP.NET 5 web 堆栈的目标之一是提供 XCOPY 部署堆栈,使 web 开发人员没有与他们的 IT 部门协调,以便能依赖更高版本。在这种情况下它也是重要的是尽量减少框架的大小,因为它需要与应用程序一起部署。

.NET 核心是本质上叉 NET 框架的执行也优化周围保理业务的关注。尽管.NET 本机 (基于触摸设备) 和 ASP.NET 5 (服务器端 web 开发) 的情况是完全不同,我们都能提供统一基类库 (BCL)。

为.NET 核心 BCL API 表面积是相同自这两个.NET 本机以及 ASP.NET 5。底部的 BCL 我们有特定于.NET 运行时非常薄层。我们目前有两种实现方式: 一是特定于本机.NET 运行时和一种特定于 CoreCLR,使用 ASP.NET 5。然而,该图层不经常改变。它包含类型,如字符串和 Int32。BCL 绝大多数是纯 MSIL 程序集可以作为共享-是。换句话说,Api 不只是看起来相同 — — 它们共享相同的实现。例如,就没有理由要集合的不同实现。

BCL,此外还有应用程序模型特定 Api。例如,.NET 本机方面提供特定于 Windows 客户端开发,如 WinRT 互操作的 Api。ASP.NET 是 5 添加如 MVC 是特定于服务器端 web 开发的 Api。

我们认为.NET 核心不是特定于.NET 本机的也 ASP.NET 5 — — BCL 和运行时环境是一般用途为模块化设计。因此,它的基础为所有未来的.NET 纵向市场。

NuGet 作为第一类运载工具

与.NET 框架,将作为一组 NuGet 包交付.NET 核心平台。我们已经落在 NuGet因为这是绝大多数图书馆生态系统已经在哪里。

为了继续我们的模块化和构造良好的努力我们不只是作为一个单一的 NuGet 包提供整个.NET 核心平台。相反,它是一套的细粒度 NuGet 程序包:

BCL 层,我们将有 1 对 1 关系之间的程序集和 NuGet 程序包。

向前,NuGet 包将具有相同的名称的程序集。例如,不可变集合不再会在一个叫做Microsoft.Bcl.Immutable的 NuGet 包传送但相反被称为System.Collections.Immutable的包中.

此外,我们已经决定为我们的程序集版本控制使用语义版本控制NuGet 软件包的版本号将程序集版本与对齐。

命名和版本控制的程序集和包之间的对齐方式极大地帮助与发现。不再是神秘的 NuGet 程序包包含 System.Foo,版本 = 1.2.3.0 — — 它由 System.Foo 包 1.2.3 版本中提供。

NuGet 允许我们以敏捷的方式交付.NET 核心。所以如果我们提供升级到任何 NuGet 程序包,您可以简单地升级相应的 NuGet 参考。

提供框架本身对 NuGet 还会移除表示 1 方.NET 依赖项之间的差异和第三方依赖关系 — — 它们是所有 NuGet 依赖项。这使第三方包来表达,例如,他们需要较高版本的 System.Collections 图书馆。安装此第三方包现在可以提示您升级您对 System.Collections 的引用。你不需要了解的依赖关系图 — — 你只需要同意对它进行更改。

NuGet 基于交货也变成一个本地应用程序框架的.NET 核心平台。.NET 核心的模块化设计保证了每个应用程序只需要部署它的需要。我们也正在启用智能共享,如果多个应用程序使用相同的框架位。然而,目标是确保每个应用程序逻辑上有它自己的框架,以便升级不会干扰其他应用程序在同一台机器上运行。

我们决定使用 NuGet 作为一种传递机制不会改变我们对兼容性的承诺。我们继续极其认真的兼容性并不会一旦包标记为稳定执行 API 或行为的重大更改。然而,应用程序本地部署确保在哪里是变化视为添加剂中断应用程序的情况很少是孤立发展时间只。换句话说,为.NET 核心这些工间休息只能发生在你升级包的引用后。在那一刻,你有两个选项: 解决在应用程序中的故障,兼容或回滚到以前的版本的 NuGet 包。但.NET 框架与那些断裂不会发生后你部署到客户或生产服务器应用程序。

企业准备好了

NuGet 部署模型使敏捷版本和更快的升级。然而,我们不想妥协,.NET 框架提供了今天的一站式服务经验。

.NET 框架的伟大的事情之一就是它作为一个整体单元,这意味着微软测试和支持所有组件作为一个单一的实体的船只。为.NET 核心我们将提供相同的体验。我们将创建一个.NET 核心分布的概念。这基本上是只是一个快照中我们对它们进行测试的特定版本的所有软件包。

这个想法是,我们的团队通常拥有单个的软件包。航运的团队的包的新版本只需要团队测试他们的组件,在他们所依赖的组件的上下文中。因为你可以混合和匹配 NuGet 程序包显然可以在某些组件的组合不好一起玩的情况。分布不会有这问题,因为所有组件在组合进行都测试。

我们期望分布在较低的节奏比单个包装发运。我们目前正在考虑一年四次。这允许为时间,它会带我们去运行必要的测试,确定签字。

虽然.NET 核心交付作为一套的 NuGet 程序包并不意味着你必须下载软件包每次你需要创建一个项目。我们会为分布提供脱机安装程序,还包括他们与 Visual Studio,以便创建新的项目将会像今天一样快速和不需要互联网连接在发展过程中。

虽然应用程序本地部署非常适合隔离的影响,走上较新的功能的依赖项它并不适用于所有情况。关键的安全修补程序必须快速部署和全面的秩序才能有效。我们都充分致力于使安全修补程序,因为我们总是对.NET。

为了避免兼容性问题,我们已经看到在过去与.NET 框架集中更新至关重要的这些唯一目标的安全漏洞。当然,还有那些破坏现有应用程序的机会很小。这就是为什么我们只有这样做的真正关键的问题,它是能接受使一组非常少的不再工作而不是所有的应用程序使用此漏洞运行的应用程序。

基础打开源和跨平台

以.NET 跨平台以可持续的方式,我们决定到开源.NET 核心.

从过去的经验我们明白成功的开放源码是它周围的社区功能。对此的一个关键方面是开放和透明的发展过程,使社区参与代码审查,读设计文件,并协助对产品的更改。

开放源代码使我们能够扩展.NET 统一,跨平台开发。如果基本的组件,如集合需要执行多次积极痛生态系统。.NET 核心的目标拥有一个单个代码库,可以用于构建和支持所有平台,包括 Windows、 Linux 和 Mac OSX。

当然,某些组件,如文件系统,需要不同的实现。NuGet 部署模型允许我们抽象掉这些差异。我们可以有一个单一的 NuGet 包,提供了一个用于每个环境的多个实现。然而,重要的部分是,这是此组件的实现细节。所有消费者都看到一个统一的 API,它发生在所有的平台工作。

另一种方式来看看这个是欲望的开放源码是欲望的延续我们释放.NET 组件用敏捷的方式:

  1. 开放源码提供准实时通信技术的实施和总体方向
  2. 释放到 NuGet.org 软件包提供在组件级敏捷
  3. 发行版提供平台一级敏捷性

在所有三个元素使得我们能够提供广泛的敏捷性和成熟。

与现有平台的.NET 核心关系

虽然我们设计.NET 核心,它将成为未来的所有堆栈的基础,我们非常了解创建"一个通用堆栈",每个人都可以使用的困境:

我们相信我们找到的未来奠定了基础,同时保持与现有堆栈大互操作性的良好平衡。我去看几个这些平台更多的细节。

.NET 框架 4.6

.NET 框架仍是选择构建丰富的桌面应用程序的平台和.NET 核心不会改变的。

视觉工作室 2015 年我们的目标是确保.NET 核心是.NET 框架的一个纯子集。换句话说,应该不会有任何功能差距。视觉工作室 2015年发布之后我们的期望是.NET 核心将快于.NET 框架的版本。这意味着功能将只在基于.NET 核心平台上可用的时间,将点。

我们将继续释放对.NET 框架的更新。我们目前的想法是,释放节奏将大致相同的今天,这是每年一次。在这些更新,我们会带我们在.NET 核心向.NET 框架的创新。我们将不只是盲目地港口各项功能的工作,虽然 — — 它将基于成本效益分析。正如我所指出的.NET 框架甚至添加剂更改可以导致现有应用程序的问题。我们的目标是尽量减少 API 和行为上的差别,同时不打破现有的.NET 框架应用程序的兼容性。

也有专门正在进行的工作,我们在WPF 路线图公布.NET 框架的投资.

单声道

你们很多人问单跨平台故事.NET 核心意味着什么。Mono 项目是本质上是开放源码的重新实现.NET 框架。它与.NET 框架分享了丰富的 Api,但也有一些问题,特别围绕执行保理业务。

单是活着,很好用顶上一个大的生态系统。这是为什么,独立的.NET 核心,我们也发布了.NET 框架参考源打开源友好的许可,在 GitHub 上部分。这样做的目的是为了使单声道社会能够使用相同的代码关闭.NET 框架和单声道之间的差距。不过,.NET 框架的复杂性我们不是安装在 GitHub 上运行它作为一个开放源代码项目。尤其是,我们无法为它接受的请求。

另一种方式,看看它:.NET 框架具有本质上是两把叉子。一把叉子由微软提供,只是 Windows。其他叉是声道,你可以使用 Linux 和 mac。

与.NET 核心我们能够制定整个.NET 堆栈作为一个完全开放源码项目。因此,不必维护单独的叉子将不再有必要: 与单声道社会我们会大力.NET 核心 Windows、 Linux 和 Mac OSX。这也使单声道的社区创新在精简的.NET 核心堆栈,以及考虑到微软不感兴趣的环境。

Windows 应用商店与 Windows Phone

Windows 商店 8.1 和 Windows Phone 8.1 平台有很多较小的.NET 框架子集。然而,他们也是.NET 核心的子集。这使我们能够使用.NET 核心作为两个向前这些平台的底层实现。所以如果你正在为这些平台将能够直接消耗所有的创新,而无需等待更新的框架。

这也意味着 BCL Api 在这两个平台上可用的数量将与那些你可以看到在 ASP.NET 5 今天完全相同。例如,这包括非泛型集合。这将使它更便于你带到触摸基于应用程序体验在.NET 框架上运行的现有代码。

另一个明显的副作用是 Windows 应用商店和 Windows Phone 中的 BCL Api 完全收敛和底层的.NET 平台现在是两个由.NET 核心供电将继续融合。

.NET 核心和其他.NET 平台之间共享代码

由于.NET 核心奠定了未来的所有.NET 平台代码与.NET 核心基于共享平台已成为无摩擦。

这里的问题代码共享如何使用不基于.NET 的核心,如.NET 框架的平台。答案是: 它像今天一样,你可以继续使用便携式类库和共享的项目:

  • 便携式类库是伟大的当你常见的代码是独立于平台的以及作为可重用的库位置的特定于平台的代码可以被分解。

  • 共享项目是代码的伟大,当你常见的代码有几位的特定于平台,因为你可以适应它与#if.

为更多细节两者之间选择,看看这篇博客.

在向前迈进,便携式类库还将支持针对.NET 核心的基础平台。唯一的区别是,如果你只有目标.NET 核心基础平台你不要一套固定的 API。相反,它基于的 NuGet 程序包,您可以在升级将。

如果您还不基于.NET 核心的至少一个平台,你被受到可以共享它的 Api。在此模式下,你仍然能够升级 NuGet 程序包,但可能会提示您选择更高的平台版本或完全放弃对他们的支持。

这种方法允许您共存在两个世界同时也获得了.NET 核心带来的好处。

  相关解决方案