一、什么是Net Core
.NET Core是适用于 windows、linux 和 macos 操作系统的免费、开源托管的计算机软件框架,是微软开发的第一个官方版本,具有跨平台 (Windows、Mac OSX、Linux) 能力的应用程序开发框架 (Application Framework),未来也将会支持 FreeBSD 与 Alpine 平台,也是微软在一开始发展时就开源的软件平台,它经常也会拿来和现有的开源 .NET 平台 Mono 比较。
由于 .NET Core 的开发目标是跨平台的 .NET 平台,因此 .NET Core 会包含 .NET Framework 的类库,但与 .NET Framework 不同的是 .NET Core 采用包化 (Packages) 的管理方式,应用程序只需要获取需要的组件即可,与 .NET Framework 打包式安装的作法截然不同,同时各包亦有独立的版本线 (Version line),不再硬性要求应用程序跟随主线版本。
.NET Core 项目的主要目标有:
支持或可以移转 (port) 到更多的操作系统平台与芯片架构 (也就是未来项目会跨出 x86 平台)。
具有引人注目的性能与高可靠度。
开发人员能快速与直接的获取 .NET Core 开发环境。
在直觉与具生产力的情况下建造应用程序,使用文件,示例与 NuGet 组件。
二、Net Core 特性
(一)、NET Core平台是开源的
.NET Core是.NET Foundation的一部分,如下图:
.NET Foundation是一个围绕.NET开发框架,并不断创新的社区。微软的另一大进步就是使ASP.NET Core开源。由于它是一个开源平台,您可以更好地控制使用和修改它,并且其代码的透明度可以为您自己的基于.NET Core的项目提供信息和灵感。此外,您和您的伙伴可以更快地更正错误和规避安全风险,使.NET Core更安全。.NET Core更稳定,因为该平台工具的代码将始终保持公开。整个框架源和包可以在GitHub站点上找到。
(二)、跨平台
除了使其成为开放源码外,微软已经不遗余力地使其跨平台。开发人员将能够在Mac,Linux或Windows系统上开发应用程序。事实上,它还引入了专门为Mac和Linux用户提供的新的代码编辑器“Visual Studio Code”。
(三)、灵活部署
.NET Core的这一功能可帮助开发人员灵活部署:作为应用程序(FDD-框架依赖部署)的一部分,或作为全新的安装(SCD-独立部署) 。FDD允许您使用较小的部署包最小化内存和磁盘空间的使用,而SCD则可以完全控制项目部署(包括.NET Core库和运行时)。
(四)、模块化架构
此功能可帮助开发人员根据项目的要求仅使用必需的软件包。模块化架构有助于升级其跨平台兼容性。因此,开发人员现在可以设计轻便,高效和强大的应用程序。与以前的版本相比,新版本相对更轻,更小,这有助于加快开发过程。对文件系统进行了较大改变,将有助于搭建健壮的开发环境。
(五)、命令行工具
与以前的版本相比,新版本更轻,更小,这有助于提高开发效率。为了搭建健壮的开发环境,文件系统作了较大变化。可以在名为DNVM或Dot Net版本管理器的命令行访问每个可能的产品方案。该命令行可以方便地更新和配置.NET运行时。这是.NET执行环境的补充。命令行的另一个好处就是它与平台无关,开发人员不需要一次又一次地学习工具链。一旦熟悉其使用,就可以在任何其他支持的平台或界面上使用相同的方式。
(六)、云支持
ASP.NET Core 是率先开发出保持云集成的功能。因为它支持基于云的配置,所以云端初始化设置允许开发人员将其应用程序方便发布到云端。
三、NET Core 或 .NET Framework,我们如何选择 ?
(一) 概述
.NET Framework支持Windows和Web应用程序。今天,您可以使用Windows Forms,WPF和UWP在.NET Framework中构建Windows应用程序。ASP.NET MVC用于在.NET Framework中构建Web应用程序。
.NET Core是为所有操作系统(包括Windows,Mac和Linux)构建应用程序的新型开源和跨平台框架。.NET Core支持UWP和ASP.NET Core,UWP用于构建Windows 10目标Windows和移动应用程序,ASP.NET Core用于构建基于浏览器的Web应用程序。通过下图您能看到.NET Core和以前的.NET Framework的主要功能区别:
同样的ASP.NET Core 与 传统的 ASP.NET 也有较大区别,如下图所示:
(二)选择.NET Core 还是.NET Framework
产品需求 | .Net Core/Framework |
使用Windows Forms和WPF的Windows客户端应用程序 | .NET Framework |
使用到WCF,WF等库的应用程序 | .NET Framework |
需要使用的第三方.NET 库或NuGet包不能用于.NET Core | .NET Framework |
需要使用不可用于 .NET Core 的 .NET 技术 | .NET Framework |
需要使用不支持 .NET Core 的平台 | .NET Framework |
预配置的环境和系统 | .NET Framework更好 |
对Dockers容器支持 | 都支持,但.NET Core更适合 |
微服务 | 都可以,但.NET Core更适合 |
跨平台需求 | .NET Core |
需要高性能和可扩展的系统 | .NET Core |
需要按应用程序级别选择并行的 .NET 版本 | .NET Core |
至2002微软公司推出.NET平台已近15年,在互联网快速迭代的浪潮中,许多语言已被淘汰,同时也有更多新的语言涌现,但 .Net 依然坚挺的站在系统开发平台的一线阵营中,并且随着.NET Core 即将到来(2016年6月27日)的正式版,势必迎来新一轮春天。
四、NET中的 Framework
要理解.NET Core就有必要了解之前的.NET平台的众多Framework们。2002年微软公司发布的第一个.NET框架————.NET Framework,不久后又发布了.NET Compact Framework 用于在较小的移动设备(Windows mobile),而.NET Compact Framework 也含有一套 类似.NET Framework 体系(Runtime, Framework,Application Model),它是一个复制精简版的 .NET Framework。在数年间微软乐此不疲的推出了数个类似 .NET Framework的框架,以用于在不同的设备和平台上运行。每个Framework都有类似的体系但又不完全相同的,这样Framework越来越多,对开发者来说不一样的设备即便功能相同也需要维护多套代码,增加了开发的复杂度。
五、NET Core的到来
微软对这些问题的重新思考和改进让.NET Core横空出世。
.NET Core是一个开源的模块化的Framework,不管是开发web或移动设备都在同一个Framework(.NET
Core)下运行,而且 .NET Core也可在不同的操作系统上运行,包括Windows、linux、MacOS,实现了跨平台跨设备。
更棒的是.NET Core 在发布程序时不用事先安装Framework而是通过Nuget下载,这样在初次部署时就不用安装一个复杂而庞大Framework,而是按需下载。这种基于Nuget的按需加载铸就了.NET Core 跨平台。
.NET Core 构成体系如下:
1. Runtime
在.NET Core 中有实现两种RunTime,NativeRuntime 和 CoreCLR。NativeRuntime 将C# 或 VB.net 代码直接转换为原生机器码。而CoreCLR是一个开源的JIT运行时,会将代码编译成中间语言(IL)在最终运行时再转换机器码。
2. Unified BCL
Base Classlibrary即基础类,例如 FileSystem、Console、XML操作等。
3. Windows Store AppModel & ASP.NET Core 1.0
提供开发Windows系统的各种触屏设备和ASP.NET程序的一组基础库。
六 .NET Core 与 .NET 其他Framework的关系
1 .NET Core & .NET Framework
.NET Core & .NET Framework 都是 NET Standard Library 的实现,一种是跨平台,而另一种是Windows下特有的,除实现NET Standard Library外 .NET Core 和 .NET Framework 都有各自特有的实现。.NET Standard Library 是跨操作系统的关键所在,它定义了一组接口,而每个操作系统有各自的实现,.NET Core通过nuget可以动态下载当前操作系统的实现,从而实现跨操作系统(暨跨操作系统共享代码)。
.NET Core 更依赖于Nuget,允许本地application在部署时动态下载需要的class library。而.NET Framework需要在系统中预装。这样.NET Core的部署比.NET Framework 更简单快速同样也更轻便。
2 .NET Core & ASP.NET
从上图可以看到 ASP.NET Core 有两种形态的存在:
ASP.NET Core Web Application(.NET Core)
依赖于.NET Core的ASP.NET 只可以调用.NET Core的API,可以在多个操作系统上运行。(可见下图下半部分的Reference Manager,在assemblies中没有.NET Framework 中的库)
ASP.NET Core Web Application(.NET Framework)
依赖于.NET Core & .NET Framework 的ASP.NET 可以调用.NET Core&.NET Framework的API ,只可以在Windows下运行。(可见下图上半部分的Reference Manager,在assemblies中含有所有.NET Framework 中的库)
3 .NET Core & Mono
Mono是.NET Framework的开源版本的实现,在某些特性上和.NET Core 很类似比如开源,跨操作系统。目前.NET CORE 会从Mono上吸取经验,发展壮大最终可以更好的在除Windows外的其他操作系统上运行。另外Mone支持的App Models要比.NET Core多(例如Windows Forms)。
七、net core的构成体系
上图描述了 .NET Core的系统构成,最上层是应用层,是开发基于UI应用的框架集,包括了ASP.NET Core(用于创建web app),和 UWP(用于创建Windows10 app)。
中间层是公共库(CoreFX),实现了.NET Standard Library ,囊括了常用系统级操作例如(文件、网络等)。
在CoreFx下是运行时环境,.NET Core 包含了两种运行时(CoreCLR、CoreRT),CoreCLR是一种基于即时编译程序(Just in time compiler,JIT)的运行时,它使用了跨平台开源的编译器RyuJIT,而CoreRT是使用提前编译器(Ahead of time compiler,AOT)的运行时,它既可以使用RyuJIT来实现AOT编译也可以使用其他的AOT编译器。由于AOT提前编译IL成了机器码,在移动设备上也具有更好的启动速度和节能性。
最后还要提到一个开源的跨平台源代码编译器Roslyn,它有别于刚才两个编译器,JIT和AOT编译器主要用于将IL编译成本机机器码,而Roslyn是将C# 或 VB.NET 代码编译成程序中间语言(intermediate language,IL)。
Roslyn 编译器
Roslyn编译器用于将C#或VB.NET代码编译为程序集(assembly),它的编译过程是一个管道式的处理过程一共包含4个步骤,具体过程见下图。
A. Parser(解析)
根据语法对源代码进行解析。
B. Declaration (声明)
为代码生成元数据(metadata),元数据是一个数据表的集合,描述了在当前代码中定义的数据类型和成员,同时也描述了引用的类型及成员。
C. Bind(绑定)
将生成的IL代码与描述它的元数据绑定在一起,生成托管模块(managed module)。
D. Emit(生成)
将一个或多个托管模块合并生成程序集(assembly)。
RyuJIT 编译器
在程序运行中需要执行某一个方法,首先需要将已经编译好的IL转换本机的机器码,而这个任务就交给了RyuJIT。它是新一代JIT编译器,第一次实现了AMD64的架构,RyuJIT能够比JIT64(上一代编译器)更快地生成代码,以提高程序运行效率(测试详情链接)。
CoreCLR & CoreRT
CoreCLR 和 CoreRT 都是.NET Core的运行时(Runtime),
它们提供了与.NET Framework CLR 类似的核心功能(内存管理、程序集加载、安全性、异常、线程管理等),可由面向于运行时的所有语言使用。
CoreRT 和 CoreCLR 不同的是,CoreRT 提供了一套
AOT 的机制,可以将.NET Core程序编译成原生代码,不依赖 .NET 运行时而运行在宿主机器上。除此之外两个运行时大部分功能代码是共享的,比如GC。AOT的优化带来不少好处:
- 编译后生成一个单文件,包含所有的依赖,包括 CoreRT,无需安装Framework
- 启动时是机器码,不需要生成机器码,也不要加载JIT编译器
- 可以使用其他优化编译器,包括 LLILC ,IL to CPP
CoreRT有两个方式生成机器码,第一个使用是直接编译IL成机器码,默认情况下,RyuJIT 作为一个 AOT 编译器将IL编译成机器码,另一个方式是将C#代码编译成C++代码,然后调用对应平台的C++编译器优化编译成机器码。
使用 RyuJIT 编译成机器码
dotnet restore
dotnet build --native --ilcpath <repo_root>\bin
\Product\Windows_NT.x64.Debug\packaging\publish1
编译生成 C++ 代码
dotnet restore
dotnet build --native --cpp --ilcpath <repo_root>\bin\Product\Windows_NT.x64.Debug\packaging\
publish1 --cppcompilerflags /MTd
CoreRT也有不足之处,它需要为不同平台编译一次;但凡事有但是,它允许工程师可以不发布到不想支持的平台(比如某游戏仅支持桌面,不支持手机)。
注:这两个命名在.NET Core RC2 版本中均无法使用,按照官方说法是在当前版本中已经移除这个命令了,具体等6月27日正式版发出后才知道最后的情况
CoreFX(.NET Core Libraries)
CoreFX主要包含数个公共库,例如 System.Collections, System.IO, System.Xml等。CoreFX是 .NET Standard Library 的实现,同样的.NET Framework 4.6.3也是基于.NET Standard Library的实现。它们目前都是基于.NET Standard Library1.6版本,具体见下表:
.NET Core 代码开发、部署、运行过程
从上图可以看到使用JIT编译和使用AOT编译源代码并运行程序是两种不同的流程。
如果使用JIT编译器部署程序时只需要将程序打包为IL的assemblies,在方法第一次执行前编译器将IL编译为目标机机器码(Native code),而AOT编译会在编译时将源代码直接编译为目标机机器码。
AOT将源代码编译为机器码,拥有如下特性:
- 用静态代码替换反射,例如如果一个值类型(value type)没有重写 ValueType.Equals 的equals的方法,默认情况判断相等,会使用反射找到filedinfo以确定type是否相等,然后再比较value是否相等。而在AOT编译中由于替换了反射因此只能比较value是否相等。
- 依赖的第三方类库以及.NET Libraries均打包至最终编译的程序中。
- 打包后的程序运行在一个精简版的运行时上(CoreRT)主要包含垃圾回收器,而运行时也会打包在app文件中。
- 虽然编译时会替换反射代码,但遇动态反射代码无能为力,运行时若遇动态反射调用则会因找不到对应的元数据及实现而抛出异常。解决办法是编译前配置运行时指令文件(Runtime directive file)指定需要用到的程序集。