·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> 魅力 .NET:从 Mono、.NET Core 说起

魅力 .NET:从 Mono、.NET Core 说起

作者:佚名      ASP.NET网站开发编辑:admin      更新时间:2022-07-23

魅力 .NET:从 Mono、.NET Core 说起

前段时间,被问了这样一个问题:.NET 应用程序是怎么运行的?

当时大概愣了好久,好像也没说出个所以然,得到的回复是:这是 .NET 程序员最基本的。。。呵呵!

微软开源,其实不只是对 .NET 本身有利,从另一方面讲,对于 .NET 程序员来说,因为开源,你可以想了解到你想要的任何事。在之前的岁月,你可以“平凡”做一个默默无闻的 C# 代码撰写者,可以不用考虑任何事,使用宇宙最强大的 IDE - Visual Studio 编写代码后,发布到 IIS 即可,就是这么简单,甚至你不需要知道 IIS 是怎么运行的,代码是怎么托管的等等,你只需要写好你的 C# 代码即可,因为其余的一切工作,微软已经帮你考虑并完成了。这样虽然简单并且高效,但对于 .NET 程序员来说,这就像“井底之蛙”一样,你看不到外面的世界,你也没有任何动力去跳出这个“深井”,而只是“舒适”的观望着外面你所认为的“狭隘世界”。但因为开源、跨平台,这些平静的日子都将被打破了,微软开源出来的一个个项目、发表的一篇篇文章,怎么越来越看不懂了?最后才发现,现在的微软已经不是原来我们熟悉的那个微软了,.NET 亦是如此。

我大概花了几天的时间,去真正阅读 .NET 开源的一些文章,虽然英文很烂,但我都坚持读了下来,阅读过程中,越来越被 .NET 的魅力所吸引,并时不时的被一些“特殊表达“所逗笑,但这都只是在阅读的过程中,读完、思考完,回到上面的那个问题,我还是不能很好的去表述、回答它,这时候我就意识到:脑子不好使,需要博客记录,这篇博文可以当做一篇阅读笔记来看(再一次的阅读)。

在很久很久之前,如果提到 .NET 跨平台,你首先想到的应该是 Mono,那 Mono 到底是什么?它为什么可以跨平台?在 .NET 开源之前,我对这些是一无所知,理解微软这次 .NET 跨平台,需要首先了解 Mono,了解 Mono,首先你需要仔细阅读下这篇文章:http://www.wikipedia.org/wiki/Mono。

摘录

Mono 是一个由 Xamarin 公司(先前是 Novell,最早为 Ximian)所主持的自由开放源代码项目。该项目的目标是创建一系列符合 ECMA 标准(Ecma-334 和 Ecma-335)的 .NET 工具,包括 C# 编译器通用语言架构。与微软的 .NET Framework(共通语言运行平台)不同,Mono 项目不仅可以运行于 Windows 系统上,还可以运行于 linux,FreeBSD,Unix,OS X 和 Solaris,甚至一些游戏平台,例如:Playstation 3,Wii 或 XBox 360。

重要的两点:

  • C# 编译器:Mono 的 C# 编译器及其相关工具发布于 GNU 通用公共许可证(GPL)之下,其运行时库发布于 GNU 宽通用公共许可证(LGPL)之下,其类库发布于 MIT 许可证之下。这些均是开源协议,因此 Mono 是一个开源软件。
  • 通用语言架构:微软开发了一个称为通用语言架构(Shared Source Common Language Infrastructure,Shared Source CLI;即今 ECMA—通用语言架构)的可用于 FreeBSD,Windows 和 Mac OS X 的 .NET 实现版本。微软的共享源代码协议并不是开源软件协议,且可能对于社区来说也是不足够的(它明文禁止了对软件的商业用途)。

再来看两个概念:

  • 公共语言基础(Common Language Infrastructure,CLI)是一套标准(ECMA335),公共语言运行时(Common Language Runtime)即 CLR 是 CLI 标准的实现,Mono 是实现者之一。该运行时用于执行已编译的 .NET 应用程序。公共语言基础已被 ECMA 定义为标准 ECMA-335。要运行一个 .NET 应用程序,你必须使用相应的参数调用运行时。通用语言基础架构定义了构成 .NET Framework 基础结构的可执行码以及代码的运行时环境的规范,它定义了一个语言无关的跨体系结构的运行环境,这使得开发者可以用规范内定义的各种高级语言来开发软件,并且无需修正即可将软件运行在不同的计算机体系结构上。

  • 公共语言规范(Common Language Specification,CLS)定义了提供给公共语言基础的接口,例如对于枚举类型的隐含表示类型的协定。Mono 的编译器负责生成符合公共语言规范的映射代码,即公共中间语言(Common Intermediate Language,CIL)。Mono 的运行时将运行这类代码。ECMA 标准先前还定义了一个符合公共语言规范的程序库作为应用框架。

理解

对于上面一大堆的协议或概念,理解起来是需要花点时间,首先 Mono 的各个部分都是基于各种开源协议,也就是说它是一个彻彻底底的开源项目,再来大致理一下协议及其实现:

  • GPLLGPL 协议: C# 编译器及其相关工具实现。
  • CLI(公共语言基础):MS CLR、Mono(CLR 虚拟机),CLR 全称为 Common Language Runtime(通用语言运行时),需要注意的是,CLR 和 .NET Framework(.NET 框架)完全不是一个概念,.NET Framework 是以一种采用系统虚拟机运行的编程平台,以 CLR 为基础,支持多种语言(C#、VB.NET、C++、Python等)的开发库。
  • CLS(公共语言规范):MSIL(微软中间语言),现已更改为 CIL,也就是通过编译器生成的中间语言。

可以用来回答博文一开始那个问题的一张图:

开发人员使用高级编程语言撰写程序,接下来编译器将代码编译成微软的中间语言(MSIL),运行的时候 CLR 会将 MSIL 代码转换为操作系统的原生代码(Native code),CLR 内置有实时编译器(中间代码转化为原生代码的编译器)。

是不是还是有点晕?其实说简单也简单,抛开应用程序和编译器,.NET 的运行机制组成,其实就只有 CIL 和 CLR,CIL 是编译器生成的中间语言,CLR 的作用就是将它再编译成原始机器代码。你可能还有一个疑问,我们常说的 .NET Framework 到底是什么?它在 .NET 运行机制中到底扮演什么角色?在上面演示图中,其实 Source Code 并不包含 .NET Framework,Source Code 指的是你应用程序的源代码,在上面有提到,.NET Framework 是以 CLR 为基础的开发库,你可以把它看作是编译好的 CIL,它并没有通过编译器的再次编译过程,而是直接通过 CLR 中的编译器编译为原始机器代码。

简要总结:

  • CLI -> CLR
  • CLS -> CIL
  • CLR 运行 CIL

好了,我们再猜想一下,如果把 .NET 运行机制的各个组件进行分开重组,除去 .NET Framework 是微软提供的,其余的组件,比如 C# 编译器、CIL、CLR 等,都是 Mono 基于各种协议进行实现的组件,那如果你的应用程序代码引用了 .NET Framework(微软实现),很显然,这个应用程序是无法运行的,因为实现的 CLR 并不是微软的 CLR,所以针对 .NET Framework 来说,因为它的不开源,所以 Mono 需要另行实现基于自己 CLR 的基础类库,但这是一个庞大而复杂的工程,所以现在的 Mono 基础类库并不是很完整,很多东西和微软的 .NET Framework 并不能很好的兼容,所以你如果使用 Visual Studio 开发的项目,想迁移到 Mono Develop 下,是非常复杂的,当然,如果你没有使用任何的 .NET Framework,是非常简单的,但现实是,敲个最简单的“Hello World”输出代码,都得引用 mscorlib.dll 程序集(System.Console)。

上面描述那么多,我想表达什么呢?其实我们现在在 Windows 平台下开发的 .NET 应用程序,是深深依赖于 .NET Framework(深深的那种),你的应用程序代码基本上都是在它之上完成的,而 .NET Framework 又是深深依赖于 Windows 平台下的 CLR(也是深深的那种),在这种情况下,根本就无法使你的应用程序跨平台,因为微软紧紧的抱住 Windows 平台,妄想 Windows 可以实现“大一统”,但现实是很残酷的,这次的 .NET 开源、跨平台,其实也是微软的无奈之举。但就是在这种背景下,Mono 出现了,并且在微软的各种“排挤”下坚持了下来,这是非常不容易的,其实实现 .NET 跨平台的三个关键是:编译器CLR基础类库,而 Mono 实质上就是把他们三个进行跨平台实现了,一个很小团队完成了一个巨头需要完成的工作,而且还是在这个巨头的“排挤”下,其实这就是开源社区的力量。

Mono 就说到这,有些疑问先放下,后面再进行讲解,下面我们来说一下 .NET Core 的相关内容。

需要认真阅读的一篇文章:.NET Core is Open Source

这是 .NET 开源的一篇官方说明文章,内容很多(包括评论),如果你真正花时间去读的话,这篇文章的信息量是非常大的,下面是我搜刮的一些片段。

.NET Core 开源地址:https://github.com/dotnet/corefx。

.NET Core 包含:

  • .NET Runtime(暂无)
  • .NET Core Framework

编译器、asp.net:

  • C# & Visual Basic ("Roslyn")
  • Visual F# Tools(暂无)
  • ASP.NET 5
  • Entity Framework

1. What is .NET Core?

答:.NET Core is a modular development stack that is the foundation of all future .NET platforms It’s already used by ASP.NET 5 and .NET Native.

关键词:Modular(模块化),现在的 .NET Core 只是增加了 .NET Core Framework 的一些代码,.NET Runtime 并未添加任何代码,这个需要时间,既然代码都未添加完善,那为什么 ASP.NET 5 and .NET Native 现在可以跨平台了?因为他们没有使用 .NET Core,而是使用独立的 Runtime-KRuntime,现在已更名为 XRE。

2. Why do we open source .NET Core?

比较“官方”的回答:

  1. Lay the foundation for a cross platform .NET.
  2. Build and leverage a stronger ecosystem.

其实翻译过来就是“形势所逼”,但事实真是如此吗?其实也不尽然,看这一段叙述就明白一些了:

The challenge is that the Windows implementation has one code base while Mono has a completely separate code base. The Mono community was essentially forced to re-implement .NET because no open source implementation was available. Sure, the source code was available since Rotor but we didn’t use an OSI apPRoved open source license, which made Rotor a non-starter. Customers have reported various mismatches, which are hard to fix because neither side can look at the code of the other side. This also results in a lot of duplicated work in areas that aren’t actually platform specific. A recent example is immutable collections.

这段叙述是很有意思的,因为 .NET 的不开源,Mono 社区重写了跨平台的 .NET,又因为 Rotor 没有基于任何 OSI 开源协议实现,所以导致 Mono 的实现充满了困难,这些都是微软亲自承认的,想想在以前,微软会说这些吗?相反它会高傲的抬起它的头,其实从这一方面就可以看出,Mono 社区这么多年是多么的不容易,微软这次的改变也是多么的不容易。为了加深你的印象,微软列举了一个最新例子:immutable collections,Mono 团队是这样写的说明:Unfortunately Microsoft didn't release their implementation under a license useable in mono I needed to reimplement the interfaces.,其实你可以看出一种无奈,Immutable Collections 是 .NET Framework 的基础核心类库之一,这还是之一,当然还有很多的实现,试想一下,如果 .NET 早就开放 .NET Framework 的源代码,即使微软没有对它进行跨平台,也会减少 Mono 团队的开发难度,以及尽量减少与 Windows 平台实现应用程序的兼容问题,当然这都是后话。

Build and leverage a stronger ecosystem.

关于这部分内容的解读,微软主要说了两点:Nuget 和 Interact,关于 Nuget,dudu 之前好像吐槽了好多次,但是微软说了,我们花了两年的时间去做这个东西,并得到了很好的反馈,但好像得到的反馈没有来自国内,使用 Nuget 的用意,其实就是之前说到的 Modular(模块化、组件化),这样的好处就是很好的扩展和维护,Interact 可以理解为开源带来的交互和进步,可以让开发者参与,并且反馈问题,利用社区的力量,让 .NET 更加完善。很有意思的是,在最后作者举了一个生活的例子:我认为这就像驾驶一辆汽车,方向盘小的调整比大的调整,更加有效果,而且也更加安全,这个小的调整可以看作是来自社区的那一份份“微小”的力量,大的调整,当然是微软自己单独搞,想想就知道哪个比较靠谱点。

3. Our choice of using GitHub

这部分也是非常有意思的,首先,微软做了一个调查,发现大部分的 .NET 社区都活跃在 GitHub 上,Don’t believe it?(看到这,我大笑了三声),不相信的话,微软给你举了一个真实的例子,nuproj(作者的一个个人项目),在 CodePlex 上放了两年,仅仅得到了一个 Pull 请求(想想也挺伤心的),然后把它移到 GitHub 上,仅仅五天后,就收到了三个 Pull 请求和两个提交,三个月的时间,总共收到了 16 个 Pull 请求和一些很有价值的提交。

作者的感受:one of the first ones was around adding unit testing, how awesome is that? 看来他是非常的激动!

需要注意的是,CodePlex 是微软构建的 Open Source 网站,它的竞争对手就是 GitHub,而微软却如此讽刺自己的“孩子”,并且放弃了它,选择了别人家的孩子,并把自己的“财产”传给它,这是需要多么大的勇气啊,虽然是迫不得已,但让一个巨头这样低头也是一件很难得的事(此处应该有掌声)。

4. Development in the open

这部分主要是讲微软如何做开源开发,提到了他们之前做的一个开源项目-Managed Extensibility Framework (MEF),他们认为这是失败的,原因很简单,就是缺少社区的参与,刚才打开这个项目看了