介绍 .NET Core

 
本人翻译(未完)
 
At connect(), we announced that .NET Core will be entirely released as open source software. I also promised to follow up with more details on .NET Core. In this post, I’ll provide an overview of .NET Core, how we’re going to release it, how it relates to the .NET Framework, and what this means for cross-platform and open source development.
在这个链接中,我们宣布.NET Core将会是一个完整发布的开源软件。我也许诺将持续介绍.NET Core的细节。在这篇推送中,我将对.NET Core进行综述,其中包括我们如何发布它,它和.NET Framework的关系,以及跨平台和开源的含义。

Looking back – motivating .NET Core

回顾 - .NET Core的开始
First let’s look back to understand how the .NET platform was packaged in the past. This helps to motivate some of the decisions and ideas that resulted in the creation of .NET Core.
首先,我们回顾一下我们是如何在过去对.NET平台进行封装的。这个过程推动我们最决定及获得一些想法,并最终创造了.NET Core。

.NET – a set of verticals

.NET - 纵向集合
When we originally shipped the .NET Framework in 2002 there was only a single framework. Shortly after, we released the .NET Compact Framework which was a subset of the .NET Framework that fit within the footprint of smaller devices, specifically Windows Mobile. The compact framework was a separate code base from the .NET Framework. It included the entire vertical: a runtime, a framework, and an application model on top.
在2002年,我们开始发布了.NET Framewowk,当时只是一个简单框架。很短的时间内,我们发布了.NET Compact Framework,这是.NET Framework的一个子集,用于满足包括封装的更新的设备,特别是Windows Mobile。这个简版框架是基于.NET Framework独立开发的。其中包括了完整的过程:一个运行时,一个框架以及顶层的应用程序模型。
Since then, we’ve repeated this subsetting exercise many times: Silverlight, Windows Phone and most recently for Windows Store. This yields to fragmentation because the .NET Platform isn’t a single entity but a set of platforms, owned by different teams, and maintained independently.
之后,我们又重复的构建了多次:Silverlight,Windows Phone以及大部分Windows商店近期的内容。这种方式使我们陷入分裂的局面,因为.NET 平台不是一个部分,而是平台的集合,由不同的团队负责,单独维护。
Of course, there is nothing wrong with offering specialized features in order to cater to a particular need. But it becomes a problem if there is no systematic approach and specialization happens at every layer with little to no regards for corresponding layers in other verticals. The outcome is a set of platforms that only share APIs by the fact that they started off from a common code base. Over time this causes more divergence unless explicit (and expensive) measures are taken to converge APIs.
当然,为满足特殊需求而提出不同的功能也不是什么错误的。但是,也因此出现一个问题,But it becomes a problem if there is no systematic approach and specialization happens at every layer with little to no regards for corresponding layers in other verticals. The outcome is a set of platforms that only share APIs by the fact that they started off from a common code base. Over time this causes more divergence unless explicit (and expensive) measures are taken to converge APIs.
 
 
 

What is the problem with fragmentation? If you only target a single vertical then there really isn’t any problem. You’re provided with an API set that is optimized for your vertical. The problem arises as soon as you want to target the horizontal, that is multiple verticals. Now you have to reason about the availability of APIs and come up with a way to produce assets that work across the verticals you want to target.

分裂会带来什么问题?如果我们只关注简单的纵向架构,这并没有什么问题。这种API集对你的纵向架构来说是最好的。而问题来源于横向,即,多个纵向架构。现在你必须考虑APIs有效性的问题,以及接下来通过期望的纵向架构来实现高质量产品的方法。

Today it’s extremely common to have applications that span devices: there is virtually always a back end that runs on the web server, there is often an administrative front end that uses the Windows desktop, and a set of mobile applications that are exposed to the consumer, available for multiple devices. Thus, it’s critical to support developers in building components that can span all the .NET verticals.

现在,我们会自然而然的开发与设备对应的应用程序:事实上会有一个后端运行web服务,用Windows desktop实现调用前端,以及一些移动应用程序用来满足消费者,以适应不同的设备。更重要的是在开发组件方面支持开发者能够满足整个.NET纵向架构。

Birth of portable class libraries

可移植类库的诞生

Originally, there was no concept of code sharing across verticals. No portable class libraries, no shared projects. You were essentially stuck with creating multiple projects, linked files, and #if. This made targeting multiple verticals a daunting task.

一开始并没有在纵向架构间开放的代码。没有可移植的类库,没有开放的解决方案。因此你被迫创建许多解决方案,关联文件。这使得以纵向架构为目标的开发让人畏惧。

In the Windows 8 timeframe we came up with a plan to deal with this problem. When we designed the Windows Store profile we introduced a new concept to model the subsetting in a better way: contracts.

在Windows 8的阶段,针对这一问题我们开始寻求解决方案。当我们设计Windows Store Profile,我们提出了对子集建模的更好的方案:契约。

Originally, the .NET Framework was designed around the assumption that it’s always deployed as a single unit, so factoring was not a concern. The very core assembly that everything else depends on is mscorlib. The mscorlib provided by the .NET Framework contains many features that that can’t be supported everywhere (for example, remoting and AppDomains). This forces each vertical to subset even the very core of the platform. This made it very complicated to tool a class library experience that lets you target multiple verticals.

在一开始,我们设计.NET Framework围绕着一个假设,即他将被用来实现简单的模块,因此我们并不关心分解。最核心的且被其他任何内容依赖的是mscorlib。mscorlib由.NET Framework提供,并包含了许多不能随意使用的功能(如Remoting,AppDomain)。这迫使他们必须垂直依赖直至平台核心。这使得开发类库经验变得非常复杂,不得不面对多个verticals。

The idea of contracts is to provide a well factored API surface area. Contracts are simply assemblies that you compile against. In contrast to regular assemblies contract assemblies are designed around proper factoring. We deeply care about the dependencies between contracts and that they only have a single responsibility instead of being a grab bag of APIs. Contracts version independently and follow proper versioning rules, such as adding APIs results in a newer version of the assembly.

契约的目的是提供一个分解得当的API接口面。契约是在编译过程需要的简单的组件。与普通组件相比,契约组件围绕着适当的因素进行设计。我们更多的关注契约和其他具备单一职责并代替grab bag的API间的依赖。契约版本是独立的且按照适当的版本规则,比如在新的组建版本中增加API结果。

We’re using contracts to model API sets across all verticals. The verticals can then simply pick and choose which contracts they want to support. The important aspect is that verticals must support a contract either wholesale or not at all. In other words, they can’t subset the contents of a contract.

我们对贯穿整个vertical进行API建模。此时vertical允许简单的使用及选择需要支持哪一种契约。最重要的方面是verticals必须广泛支持或不支持。换句话说,他们不能subset契约的内容。

This allows reasoning about the API differences between verticals at the assembly level, as opposed to the individual API level that we had before. This aspect enabled us to provide a class library experience that can target multiple verticals, also known as portable class libraries.

这使得我们可以进行组件层的vertical设计,而不再和之前一样面对个别API层面。这方面使得我们能够提供面对多个vertical及可移植类库的经验。

Unifying API shape versus unifying implementation

整合API模型与整合实现模块

You can think of portable class libraries as an experience that unifies the different .NET verticals based on their API shape. This addressed the most pressing need, which is the ability to create libraries that run on different .NET verticals. It also served as a design tool to drive convergence between verticals, for instance, between Windows 8.1 and Windows Phone 8.1.

你可以把可移植类库当作基于整合不同的.NET verticals的API后的积累模块(experence)。创建一个在不同.NET verticals上可用的类库的能力是迫切需要的。这也可以当作设计工具用于vertical间统一。比如Windows8.1和Windows Phone8.1。

However, we still have different implementations – or forks – of the .NET platform. Those implementations are owned by different teams, version independently, and have different shipping vehicles. This makes unifying API shape an ongoing challenge: APIs are only portable when the implementation is moved forward across all the verticals but since the code bases are different that’s fairly expensive and thus always subject to (re-)prioritization. And even if we could do a perfect job with converging the APIs: the fact that all verticals have different shipping vehicles means that some part of the ecosystem will always lag behind.

然后,我们仍然有不同的平台的实现(模块)或分支。他们由不同的团队负责,版本独立,同时有不同的发布渠道。这使得整合API模型存在前进的挑战:只有在所有vertical的模块向前升级时,API是具有可移植性的。但由于他们基于的代码不同,需要昂贵的代价且总是 subject to (re-)prioritization. 即使我们可以将整合API的工作做的很好:实际上所有的vertical有不同的发布渠道,这意味着生态系统的部分总是滞后的。

 

A much better approach is unifying the implementations: instead of only providing a well factored view, we should provide a well factored implementation. This would allow verticals to simply share the same implementation. Convergence would no longer be something extra; it’s achieved by construction. Of course, there are still cases where we may need multiple implementations. A good example is file I/O which requires using different technologies, based on the environment. 

更好的方法是整合现有实现模块:代替之提供考虑多方面因素的视角。我们需要提供考虑多方面因素的具体实现。这使得verticals可以简单的共享实现。统一不再遥不可及;通过架构得以实现。当然仍然存在需要独立实现的模块。比如文件I/O需要基于不同环境的技术。

However, it’s a lot simpler to ask each team owning a specific component to think about how their APIs work across all verticals than trying to retroactively providing a consistent API stack on top. That’s because portability isn’t a something you can provide later. For example, our file APIs include support for Windows Access Control Lists (ACL) which can’t be supported in all environments. The design of the APIs must take this into consideration, and, for instance, provide this functionality in a separate assembly that can be omitted on platforms that don’t support ACLs.

然后,让每个组考虑他们API在多个verticals兼容比尝试从头开始清理API要简单。这是因为可移植性不是你以后需要考虑的。例如,我们的文件API包含支持Windows Access Controls Lists,他并不能在所有的环境下使用。API设计必须结合这一点考虑,同时,这些特殊组件的共呢个也会被其他不需要ACLs支持的平台所忽略。

Machine-wide frameworks versus application-local frameworks

跨设备框架与应用本地框架

Another interesting challenge has to do with how the .NET Framework is deployed.

另外一个有趣的挑战则是如何对.NET Framework进行部署。

The .NET Framework is a machine-wide framework. Any changes made to it affect all applications taking a dependency on it. Having a machine-wide framework was a deliberate decision because it solves those issues:

.NET Framework是一个跨设备的框架,任何改变都依赖他的应用都会生效。使用跨设备框架的方案是一个慎重的决定,因为他解决了下面几点:

  1. It allows centralized servicing
  2. It reduces the disk space
  3. Allows sharing native images between applications
1. 允许集中式服务
2. 减少磁盘空间
3. 允许多个应用间分享本地图片影像

But it also comes at a cost.

但这也带来一些开销。

For one, it’s complicated for application developers to take a dependency on a recently released framework. You either have to take a dependency on the latest OS or provide an application installer that is able to install the .NET Framework when the application is installed. If you’re a web developer you might not even have this option as the IT department tells you which version you’re allowed to use. And if you’re a mobile developer you really don’t have choice but the OS you target.

举一个例子,对应用程序开发人员来说,依赖一个最新发布的框架是很复杂的。你不得不依赖最新的操作系统,或当安装应用程序时提供的应用安装程序以支持.NET Framework的安装。如果你是web开发人员,你甚至不需要选择IT部门告诉你可用的版本。同时如果你是移动端开发人员,你就不得不面向操作系统进行开发了。

But even if you’re willing to go through the trouble of providing an installer in order to chain in the .NET Framework setup you may find that upgrading the .NET Framework can break other applications.

但即使你认为按照.NET Framework安装需求提供安装程序不是问题,你可能发现,升级.NET Framework使得其他的应用程序无法执行了。

Hold on – aren’t we saying that our upgrades are highly compatible? We are. And we take compatibility extremely seriously. We have rigorous reviews for any changes made to the .NET Framework. And for anything that could be a breaking change we have dedicated reviews to investigate the impact. We run a compat lab where we test many popular .NET applications to ensure that we don’t regress them. We also have the ability to tell which .NET Framework the application was compiled against. This allows us to maintain compatibility with existing applications while providing a better behavior for applications that opted-into targeting a later version of the .NET Framework.

等一下,我们不是在说高兼容性的升级吗?是的,我们确实说的是兼容性问题。我们重新审视了.NET Framework的所有变化。同时也考虑了任何可能打破变化的可能。我们慎重的态度研究了影响。我们组建了一个兼容性实验室,在这里我们对流行的.NET 应用程序进行测试,确保我们没有倒退。我们也能力指明哪一些.NET Framework 是应用程序无法编译的。这使我们能够维护已有应用程序的兼容性,并向应用程序提供更好的信息以选择是否关注最新发布的.NET Framework。

Unfortunately, we’ve also learned that even compatible changes can break applications. Let me provide a few examples:

不幸的是,我们从中发现一些兼容性改变破坏了应用程序,下面据一些例子:

  • Adding an interface to an existing type can break applications because it might interfere with how the type is being serialized.

    在现有类型中增加一个接口会是应用程序无法使用,因为这将干预类型如何被序列化

  • Adding an overload to a method that previously didn’t had any overloads can break reflection consumers that never handled finding more than one method.

    增加一个之前没有重载过的重载方法会使反射consumers由于无法找到一个或多个方法导致无法工作。

  • Renaming an internal type can break applications if the type name was surfaced via a ToString() method.

    如果一个类型存在ToString()方法调用,那么重命名这个内部类型导致应用程序无法工作。

Those are all rare cases but when you have a customer base of 1.8 billion machines being 99.9% compatible can still mean that 1.8 million machines are affected.

Interestingly enough, in many cases fixing impacted applications is fairly trivial. But the problem is that the application developer isn’t necessarily involved when the break occurs. Let’s look at a concrete example.

这些都是特殊情况,但是当你客户有18亿个设备并有99.9%的兼容性时,这意味着180万个设备受影响。更有趣的是,在很多情况下,解决受影响的应用程序是微不足道的。当故障发生时,应用程序开发人员不会受到牵连。让我们看一个实际的例子。

You tested your application on .NET Framework 4 and that’s what you installed with your app. But some day one of your customers installed another application that upgraded the machine to .NET Framework 4.5. You don’t know your application is broken until that customer calls your support. At this point addressing the compat issue in your application is fairly expensive as you have to get the corresponding sources, setup a repro machine, debug the application, make the necessary changes, integrate them into the release branch, produce a new version of your software, test it, and finally release an update to your customers.

Contrast this with the case where you decide you want to take advantage of a feature released in a later version of the .NET Framework. At this point in the development process, you’re already prepared to make changes to your application. If there is a minor compat glitch, you can easily handle it as part of the feature work.

你在.NET Framework4上测试你的应用程序,他随你的应用一同安装。但突然某一天,你的客户安装其他应用程序并升级.NET Framework4.5。同时,在客户联系你需要维护前,你不知道你的应用程序已经崩溃。而去解决应用程序的问题会付出相当的代价。你必须获取相应的资源数据,安装在相同的设备上,调试应用程序,进行必要的修改,在新的发布分支中进行整合,生产新的软件版本,并测试,最后在客户端进行升级。相比这种方式,你决定你采纳新发布.NET Framework中更好的功能。在开发过程中,你已经为升级应用程序做好了准备。如果有较小影响干扰,你能够很快的解决这部分问题。

Due to these issues, it takes us a while to release a new version of the .NET Framework. And the more drastic the change, the more time we need to bake it. This results in the paradoxical situation where our betas are already fairly locked down and we’re pretty much unable to take design change requests.

Two years ago, we’ve started to ship libraries on NuGet. Since we didn’t add those libraries to the .NET Framework we refer to them as “out-of-band”. Out-of- band libraries don’t suffer from the problem we just discussed because they are application-local. In other words, the libraries are deployed as if they were part of your application.

归咎于此,这需要一些时间发布新的.NET Framework版本。同时我们越大的变更我们酝酿的时间越长。与此状况相反的情况,我们的测试版本已经确定,我们已经在接受设计变更的请求。

This pretty much solves all the problems that prevent you from upgrading to a later version. Your ability to take a newer version is only limited by your ability to release a newer version of your application. It also means you’re in control which version of the library is being used by a specific application. Upgrades are done in the context of a single application without impacting any other application running on the same machine.

这个方式解决了你升级至最新版本的所有困扰。你能否发布新版本受限于你的能力是否支持你升级你的应用程序。这也意味着你能够控制版本与特定应用程序的关系。在同一个设备上运行不影响其他的应用程序情况下,可以升级软件了。

This enables us to release updates in a much more agile fashion. NuGet also provides the notion of preview versions which allow us to release bits without yet committing on a specific API or behavior. This supports a workflow where we can provide you with our latest design and – if you don’t like it – simply change it. A good example of this is immutable collections. It had a beta period of about nine months. We spend a lot of time trying to get the design right before we shipped the very first version. Needless to say that the final design – thanks to the extensive feedback you provided – is way better than the initial version.

这使得我们发布更新更加灵活。NuGet也提供了版本纵览的概念。这使我们能够在不关注于某个API或行为的情况下发布变更。他也支持工作流,我们可以提供最新的设计,但如果你不喜欢,可以改变他。最好的例子就是不可改变的集合。他又9个月的beta测试阶段。在发布之前,我们花费大量时间使之正确。不用说,最后的设计比最初的设计好很多,感谢大家提供的大量反馈。

Enter .NET Core

走进 .NET Core

All these aspects caused us to rethink and change the approach of modelling the .NET platform moving forward. This resulted in the creation of .NET Core:

所有这些方面让我们反思并对 .NET 平台建模改进方法进行改变。.NET Core 创造的结果如下:

 

.NET Core is a modular implementation that can be used in a wide variety of verticals, scaling from the data center to touch based devices, is available as open source, and is supported by Microsoft on Windows, Linux and Mac OSX. 

.NET Core是一个模块化实现,这使得它能够广泛的应用在各个verticals中。引导数据中心访问基础设备,就像开源一样有效,由Microsoft在Windows,Linuxhe Max OSX上支持。

Let me go into a bit more detail of how .NET Core looks like and how it addresses the issues I discussed earlier.

让我们走进.NET Core 更近一些,它到底是怎么样的,以及他是如何如何实现我之前描述的内容。

Unified implementation for .NET Native and ASP.NET

为.NET Native 和 APS.NET进行整合实现

When we designed .NET Native it was clear that we can’t use the .NET Framework as the foundation for the framework class libraries. That’s because .NET Native essentially merges the framework with the application, and then removes the pieces that aren’t needed by the application before it generates the native code (I’m grossly simplifying this process here. For more details, take a look at this deep dive). As I explained earlier, the .NET Framework implementation isn’t factored which makes it quite challenging for a linker to reduce how much of the framework gets compiled into the application – the dependency closure is just too large.

当我们设计.NET Native时,我们确认不会使用.NET Framework作为架构类库的基础。这是因为.NET Native本质上融合了应用程序的架构,以及移除了那些在集成native代码的应用程序的应用程序不需要的部分(我只是简略的描述这个过程,获取更多信息,可以看这个链接deep dive)。正如我之前解释的那样,.NET Framework的实现不会被分解,这使得实现相当有挑战,通过连接器减少编译到程序中的框架的数量-依赖的移除的部分太大了。

ASP.NET 5 faced similar challenges. Although it doesn’t use .NET Native one of the goals of the new ASP.NET 5 web stack was to provide an XCOPY deployable stack so that web developers don’t have coordinate with their IT department in order to take dependencies on later versions. In that scenario it’s also important to minimize the size of the framework as it needs to be deployed alongside the application.

ASP.NET 5 面对着类似的挑战。尽管他不使用.NET Native。ASP.NET 5 web堆其中一个目的是提供XCOPY部署堆,这样web开发人员不需要与IT部门进行确认,对后期版本更有信心。在那样的场景中,减少框架的尺寸也是很重要的,因为他需要和应用程序一同部署。

.NET Core is essentially a fork of the NET Framework whose implementation is also optimized around factoring concerns. Even though the scenarios of .NET Native (touch based devices) and ASP.NET 5 (server side web development) are quite different, we were able to provide a unified Base Class Library (BCL).

.NET Core本质是一个.NET Framwork的分支。他以平衡围绕各种问题最佳的方式实现。即使.NET Native的场景(与基础设备交互)和ASP.NET 5(服务端web开发)区别非常大,我们也能够提供统一的基础类库(BCL)。

The API surface area for the .NET Core BCL is identical for both .NET Native as well ASP.NET 5. At the bottom of the BCL we have a very thin layer that is specific to the .NET runtime. We’ve currently two implementations: one is specific to the .NET Native runtime and one that is specific to CoreCLR, which is used by ASP.NET 5. However, that layer doesn’t change very often. It contains types like String and Int32. The majority of the BCL are pure MSIL assemblies that can be shared as-is. In other words, the APIs don’t just look the same – they share the same implementation. For example, there is no reason to have different implementations for collections.

On top of the BCL, there are app-model specific APIs. For instance, the .NET Native side provides APIs that are specific to Windows client development, such as WinRT interop. ASP.NET 5 adds APIs such as MVC that are specific to server- side web development.

We think of .NET Core as not being specific to either .NET Native nor ASP.NET 5 – the BCL and the runtimes are general purpose and designed to be modular. As such, it forms the foundation for all future .NET verticals.

NuGet as a first class delivery vehicle

In contrast to the .NET Framework, the .NET Core platform will be delivered as a set of NuGet packages. We’ve settled on NuGet because that’s where the majority of the library ecosystem already is.

In order to continue our effort of being modular and well factored we don’t just provide the entire .NET Core platform as a single NuGet package. Instead, it’s a set of fine grained NuGet packages:

For the BCL layer, we’ll have a 1-to-1 relationship between assemblies and NuGet packages.

Moving forward, the NuGet package will have the same name as the assembly. For example, immutable collections will no longer be delivered in a NuGet package called Microsoft.Bcl.Immutable but instead be in a package called System.Collections.Immutable.

In addition, we’ve decided to use semantic versioning for our assembly versioning. The version number of the NuGet package will align with the assembly version.

The alignment of naming and versioning between assemblies and packages help tremendously with discovery. There is no longer a mystery which NuGet packages contains System.Foo, Version=1.2.3.0 – it’s provided by the System.Foo package in version 1.2.3.

NuGet allows us to deliver .NET Core in an agile fashion. So if we provide an upgrade to any of the NuGet packages, you can simply upgrade the corresponding NuGet reference.

Delivering the framework itself on NuGet also removes the difference between expressing 1st party .NET dependencies and 3rd party dependencies – they are all NuGet dependencies. This enables a 3rd party package to express, for instance, that they need a higher version of the System.Collections library. Installing this 3rd party package can now prompt you to upgrade your reference to System.Collections. You don’t have to understand the dependency graph – you only need to consent making changes to it.

The NuGet based delivery also turns the .NET Core platform into an app-local framework. The modular design of .NET Core ensures that each application only needs to deploy what it needs. We’re also working on enabling smart sharing if multiple applications use the same framework bits. However, the goal is to ensure that each application is logically having its own framework so that upgrading doesn’t interfere with other applications running on the same machine.

Our decision to use NuGet as a delivery mechanism doesn’t change our commitment to compatibility. We continue to take compatibility extremely seriously and will not perform API or behavioral breaking changes once a package is marked as stable. However, the app-local deployment ensures that the rare case where a change that is considered additive breaks an application is isolated to development time only. In other words, for .NET Core these breaks can only occur after you upgraded a package reference. In that very moment, you have two options: addressing the compat glitch in your application or rolling back to the previous version of the NuGet package. But in contrast to the .NET Framework those breaks will not occur after you deployed the application to a customer or the production server.

Enterprise ready

The NuGet deployment model enables agile releases and faster upgrades. However, we don’t want to compromise the one-stop-shop experience that the .NET Framework provides today.

One of the great things of the .NET Framework is that it ships as a holistic unit, which means that Microsoft tested and supports all components as a single entity. For .NET Core we’ll provide the same experience. We’ll create the notion of a .NET Core distribution. This is essentially just a snapshot of all the packages in the specific version we tested them.

The idea is that our teams generally own individual packages. Shipping a new version of the team’s package only requires that the team tests their component, in the context of the components they depend on. Since you’ll be able to mix- and-match NuGet packages there can obviously be cases where certain combinations of components don’t play well together. Distributions will not have that problem because all components are tested in combination.

We expect distributions to be shipped at a lower cadence than individual packages. We are currently thinking of up to four times a year. This allows for the time it will take us to run the necessary testing, fixing and sign off.

Although .NET Core is delivered as a set of NuGet packages it doesn’t mean that you have to download packages each time you need to create a project. We’ll provide an offline installer for distributions and also include them with Visual Studio so that creating new projects will be as fast as today and not require internet connectivity in the development process.

While app-local deployment is great for isolating the impact of taking dependencies on newer features it’s not appropriate for all cases. Critical security fixes must be deployed quickly and holistically in order to be effective. We are fully committed to making security fixes as we always have for .NET.

In order to avoid the compatibility issues we have seen in the past with centralized updates to the .NET Framework it’s essential that these only target the security vulnerabilities. Of course, there is still a small chance that those break existing applications. That’s why we only do this for truly critical issues where it’s acceptable to cause a very small set of apps to no longer work rather than having all apps run with the vulnerability.

Foundation for open source and cross platform

In order to take .NET cross platform in a sustainable way we decided to open source .NET Core.

From past experience we understand that the success of open source is a function of the community around it. A key aspect to this is an open and transparent development process that allows the community to participate in code reviews, read design documents, and contribute changes to the product.

Open source enables us to extend the .NET unification to cross platform development. It actively hurts the ecosystem if basic components like collections need to be implemented multiple times. The goal of .NET Core is having a single code base that can be used to build and support all the platforms, including Windows, Linux and Mac OSX.

Of course, certain components, such as the file system, require different implementations. The NuGet deployment model allows us to abstract those differences away. We can have a single NuGet package that provides multiple implementations, one for each environment. However, the important part is that this is an implementation detail of this component. All the consumers see a unified API that happens to work across all the platforms.

Another way to look at this is that open source is a continuation of our desire to release .NET components in an agile fashion:

  1. Open Source offers quasi real-time communication for the implementation and overall direction
  2. Releasing packages to NuGet.org offers agility at the component level
  3. Distributions offer agility at the platform level

Having all three elements allows us to offer a broad spectrum of agility and maturity.

Relationship of .NET Core with existing platforms

Although we’ve designed .NET Core so that it will become the foundation for all future stacks, we’re very much aware of the dilemma of creating the “one universal stack” that everyone can use:

We believe we found a good balance between laying the foundation for the future while maintaining great interoperability with the existing stacks. I’ll go into more detail by looking at several of these platforms.

.NET Framework 4.6

The .NET Framework is still the platform of choice for building rich desktop applications and .NET Core doesn’t change that.

For Visual Studio 2015 our goal is to make sure that .NET Core is a pure subset of the .NET Framework. In other words, there wouldn’t be any feature gaps. After Visual Studio 2015 is released our expectation is that .NET Core will version faster than the .NET Framework. This means that there will be points in time where a feature will only be available on the .NET Core based platforms.

We’ll continue to release updates to .NET Framework. Our current thinking is that the release cadence will roughly be the same as today, which is about once a year. In these updates, we’ll bring the innovations that we made in .NET Core to the .NET Framework. We’ll not just blindly port all the feature work, though – it will be based on a cost-benefit analysis. As I pointed out, even additive changes to the .NET Framework can cause issues for existing applications. Our goal is to minimize API and behavioral differences while not breaking compatibility with existing .NET Framework applications.

There are also investments that are exclusively being made for the .NET Framework such as the work we announced in the WPF Roadmap.

Mono

Many of you asked what the .NET Core cross platform story means for Mono. The Mono project is essentially an open source re-implementation of the .NET Framework. As such, it shares the richness of the APIs with the .NET Framework but it also shares some of its problems, specifically around the implementation factoring.

Mono is alive and well with a large ecosystem on top. That’s why, independent of .NET Core, we also released parts of the .NET Framework Reference Source under an open source friendly license on GitHub. This was done to allow the Mono community to close the gaps between the .NET Framework and Mono by using the same code. However, due to the complexity of the .NET Framework we’re not setup to run it as an open source project on GitHub. In particular, we’re unable to accept pull requests for it.

Another way to look at it: The .NET Framework has essentially two forks. One fork is provided by Microsoft and is Windows only. The other fork is Mono which you can use on Linux and Mac.

With .NET Core we’re able to develop an entire .NET stack as a full open source project. Thus, having to maintain separate forks will no longer be necessary: together with the Mono community we’ll make .NET Core great for Windows, Linux and Mac OSX. This also enables the Mono community to innovate on top of the leaner .NET Core stack as well as taking it to environments that Microsoft isn’t interested in.

Windows Store & Windows Phone

Both the Windows Store 8.1 and Windows Phone 8.1 platforms are much smaller subsets of the .NET Framework. However, they are also a subset of .NET Core. This allows us to use .NET Core as the underlying implementation for both of these platforms moving forward. So if you’re developing for those platforms you are able to directly consume all innovations without having to wait for an updated framework.

It also means that the number of BCL APIs available on both platforms will be identical to the ones you can see in ASP.NET 5 today. For example, this includes non-generic collections. This will make it much easier for you to bring existing code that runs on top of the .NET Framework into the touch-based application experience.

Another obvious side effect is that the BCL APIs in Windows Store and Windows Phone are fully converged and will remain converged as the underlying .NET platform is now both powered by .NET Core.

Sharing code between .NET Core and other .NET platforms

Since .NET Core forms the foundation for all future .NET platforms code sharing with .NET Core based platforms has become friction free.

This raises the question how code sharing works with platforms that aren’t based on .NET Core, such as the .NET Framework. The answer is: it’s the same as today, you can continue to use portable class libraries and shared projects:

  • Portable class libraries are great when your common code is platform-independent as well as for reusable libraries where the platform-specific code can be factored out.

  • Shared projects are great when your common code has a few bits of platform-specific code, since you can adapt it with #if.

For more details on how choose between the two, take a look at this blog post.

Moving forward, portable class libraries will also support targeting .NET Core based platforms. The only difference is that if you only target .NET Core based platforms you don’t get a fixed API set. Instead, it’s based on NuGet packages that you can upgrade at will.

If you also target at least one platform that isn’t based on .NET Core, you’re constrained by the APIs that can be shared with it. In this mode, you’re still able to upgrade NuGet packages but you may get prompted to select higher platform versions or completely drop support for them.

This approach allows you to co-exist in both worlds while still reaping the benefits that .NET Core brings.

Summary

The .NET Core platform is a new .NET stack that is optimized for open source development and agile delivery on NuGet. We’re working with the Mono community to make it great on Windows, Linux and Mac, and Microsoft will support it on all three platforms.

We’re retaining the values that the .NET Framework brings to enterprise class development. We’ll offer .NET Core distributions that represent a set of NuGet packages that we tested and support together. Visual Studio remains your one- stop-shop for development. Consuming NuGet packages that are part of a distribution doesn’t require an internet connection.

We acknowledge our responsibility and continue to support shipping critical security fixes without requiring any work from the application developer, even if the affected component is exclusively distributed as NuGet package.

Questions or concerns? Let us know by commenting on this post, by sending a tweet to @dotnet, or by starting a thread in the .NET Foundation forums. Looking forward to hearing from you!

 
词汇说明:
Subsetting
Span
Implementations:实现的模块功能
Multiple Implementations:对于多个vertical,对应每一个vertical包含一套独立的Implementation,而整体来说也就是Multiple Implementations。
posted @ 2017-08-25 13:05  sunlyk  阅读(369)  评论(0编辑  收藏  举报