2016 年 4 月

第 31 卷,第 4 期

.NET Core - .NET 使用 .NET Core 跨平台运行

作者 Phillip Carter | 2016 年 4 月

我们正在 Microsoft 中构建全新的.NET 实现(称之为 .NET Core),可让您针对云优化的工作负载编写跨平台代码。很多人对这一开源开发很感兴趣,但它的实际意义是什么呢? 本文应可帮助阐明 .NET Core 的意义及其目标,其与 Microsoft .NET Framework 的关联,以及您可以用于 .NET Core 入门的命令行工具基础。

什么是 .NET Core?

要理解 .NET Core 的含义,我们有必要先理解 .NET 本身。很多人在提到“.NET”时是指“.NET Framework”,但“.NET”的含义远不止如此。.NET 是具有多种实现(.NET Framework、Mono、Unity 和现在的 .NET Core)的 ECMA 标准。这意味着多种体验都在 .NET Framework 和 .NET Core 之间共享。但是,.NET Core 是全新的,有一些令人印象深刻的不同原则。

首先,.NET Core 是跨平台的。它可在 Windows、OS X 和 Linux 的多个发布版本上运行。它还支持不同的 CPU 体系结构。我们正在添加更多的 Linux 发布版本和 CPU 体系结构支持,最终目的是使 .NET Core 在尽可能多的环境中运行。

同时,.NET Core 在设计和体系结构上基本是模块化的。它的运行时、库和编译器组件均为独立的实体,并通过设计良好的接口进行通信。这可以让您针对特定需求“换入”和“换出”组件。库本身也是模块化的,并通过 NuGet 分布,这样,您就可以只使用需要的内容,以在任意给定系统上优化 .NET Core 的占用。

另外,针对 .NET Core 编写的代码是可移植的,并可被调整为在所支持的不同平台间运行。根据您决定项目目标的方式,.NET Core 代码可能会在 .NET Framework、Mono 和 Xamarin 平台、Windows 8 和 Windows Phone 以及通用 Windows 平台 (UWP) 上运行。要了解更多信息,请查看 .NET 平台标准 (bit.ly/1Of6W1r)。

最后,.NET Core 会成为“付费”的高性能实现。.NET Core 的目标之一在于,通过实现付费模式,清楚地表示出采用更高级别的抽象解决问题而产生的费用,使开发人员明确抽象成本。抽象并不是免费使用的,而且,决不应该对开发人员隐藏这一事实。另外,.NET Core 可使用标准库提升性能,标准库可最大程度地降低系统中的分配和总体内存占用。

.NET Core 方案

现在有四种方案,您可以在其中编写针对 .NET Core 的代码:跨平台 ASP.NET Web 应用、跨平台控制台应用、跨平台库和框架、UWP 应用

ASP.NET Core 1.0 是用于 .NET Core 的跨平台 Web 堆栈,采用高速设计。如果您曾经想进行将 ASP.NET Web 应用部署到 Linux 容器上之类的操作,现在您可以做到了。要了解更多有关 ASP.NET Core 提供的多种功能的信息,请前往 bit.ly/1TqPcIo 查看文档。

跨平台控制台应用的范围比很多开发人员所预期的要大很多。例如,就本质而言,ASP.NET Core Web 应用是读取信息并将信息写入端口的控制台应用—它只是恰好能进行许多其他操作。一套形成整个系统后端的微服务均可被编写为控制台应用。

跨平台库和框架之间的区别之一在于其规模。库是在 .NET Core 上构建功能的最自然的候选对象之一。但是在更大的范围上,用于分布式计算的框架也是极佳的候选对象。

最后,以 Windows 10 设备系列为目标的 UWP 应用可在 .NET Core 上运行。您可以构建包含了 .NET Core 库的功能完善的 UWP 应用,以帮助构建丰富的 Windows 10 应用。

换句话说,现在您可以针对 .NET Core 编写多种内容。随着工具的成熟和扩展,将来,您还可以构建更多内容。

如果您的 .NET Framework 资产属于这四种方案中的一种,或您想尝试部分新技术,请转到 bit.ly/1Q1Q18q,您可以在这里编写部分 .NET Core 代码。

.NET Core 与 .NET Framework 的比较结果

大部分人了解并喜爱的 .NET 被称作 .NET Framework。那么,.NET Core 与 .NET Framework 的比较结果如何呢? 首先请记住,您仍然使用相同的语言(C#、F#、Visual Basic)编写所有代码。从视觉和感觉上来说,您编写代码的体验应该非常相似。但是,.NET Core 是新的堆栈,而非 .NET Framework 的子集。最好将 .NET Core 和 .NET Framework 看作两个重合且共同进化的堆栈。

编写用于 Windows 7 到 Windows 10 的桌面应用程序时,现在和将来使用的都是 .NET Framework 堆栈。事实上,您可以让 .NET Framework 和 .NET Core 代码在同一解决方案中和谐共存。例如,请考虑一个方案,其中,.NET Framework GUI(例如 Windows 窗体)使用的是在 .NET Core 上编写的服务。

我们可以从两个方面来看待 .NET Core 和 .NET Framework 之间的异同。 API 外围应用和运行时功能。图 1 说明了两个平台之间的 API 重叠。

.NET Framework 和 .NET Core 共享一个 API 子集
图 1:.NET Framework 和 .NET Core 共享一个 API 子集

.NET Core 和 .NET Framework 上均实现了 .NET API(虽然有时底层的实现不同)。同时,.NET Core 和 .NET Framework 均有对方不具备的 API 和功能。例如,.NET Framework 有多个 .NET Core 不具备的 GUI 框架和特定于 Windows 的 API。同样地,.NET Core 有 .NET Framework 缺少的跨平台功能和 API。

另外,.NET Framework 是通过 Windows 更新获得服务的 Windows 组件。而 .NET Core 的存在环境和服务获取方式则采用完全不同的模式。.NET Core 包括 NuGet 包,并带有安装了运行时的本地应用。这就意味着应用程序可以“携带”.NET Core,这让它们可以在计算机或设备上与其他 .NET Core 实例并行存在。这样,服务就可以通过程序包管理器应用于每个应用程序,而无需通过 OS 更新全局应用。

下面提一个实际的问题: 如果您在一个堆栈上编写代码,它会在别的堆栈上运行吗? 和生活中的大部分问题一样,这要视情况而定。如果您使用的 API 在两个平台上均得以实现,那么,您执行较少的工作就能在 .NET Core 和 .NET Framework 上运行您的代码了。但是,如果您在运行环境中假定了依赖项,或使用了不适用于其中一个堆栈的 API(例如,用于使用基于 XAML 的 UI 的库),则您的代码将不会在两个堆栈上运行。.NET Portability Analyzer—可用作命令行工具 (bit.ly/1Sd8oIK) 或 Visual Studio 扩展 (bit.ly/1LqX0aF)—这是一个工具,用于分析您的 .dll 文件,并就如何将您的代码从 .NET Framework 移植到 .NET Core 生成报告。以后,我们将发布更多帮助移植的工具。

命令行: 您的 .NET Core 入口点

.NET Core 带有全新和改进的基础工具集,可用于开发应用程序。该工具集被称为 .NET Core CLI,即 .NET Core 命令行接口的缩写。与 .NET Core 的其他部分相同,它也是开源的(请参阅 GitHub.com/dotnet/cli),并具有一个与其开发紧密相关的充满活力的开源社区。

引入新的工具集有多个原因。首先,我们有必要在 .NET Core 支持的所有平台上支持核心开发方案。考虑到不同的平台,良好的命令行体验是一个可供我们构建的绝佳的基础;毕竟,命令行是每个平台默认的自带内容。

作为逻辑扩展,我们希望在支持的各平台上支持相同的 UX。您可以在 Linux、Windows 和 OS X 之间转移,而无需重新学习它们的工具、语法或语义。所有平台上的这些内容都是相同的。使用模式甚至语法都是相同的。

您可以跨平台使用一个工具集的想法还扩展到了更高级别的工具,即 Visual Studio Code 和 Visual Studio。这些更高级别的工具将会在 .NET CLI 上分层,并用它们支持 .NET Core 项目的发展。这就意味着,当您通过 Visual Studio 构建 .NET Core 应用程序时,.NET CLI 工具将被调用于执行这一构建。

尝试 .NET Core 命令行界面

最简单的 .NET Core CLI 入门方式就是遵循入门指南 (aka.ms/dotnetcoregs)。简言之,就是下载适用于平台的安装程序(如果使用 Ubuntu,则注册一个新的 apt-get 源)并安装工具,这样就准备就绪了。安装程序会负责在所有支持的 OS 的系统路径上设置好安装文件夹,以及 CLI 需要的其他任何环境变量。

之后,您可以通过调用“dotnet”驱动程序并传递命令(我们也称之为“谓词”)进行启动。驱动程序负责运行命令并向其传递所有参数。在本次编写过程中,CLI 包会带有图 2 中的命令。当然,当您读取这一命令时,我们可能会添加更多提升生产效率的命令。

图 2:您可以立即使用的部分通用 .NET CLI 命令

命令 说明
dotnet new 使用 C# 语言初始化用于类库或控制台应用程序的有效项目。
dotnet restore 还原在指定项目的 project.json 文件中定义的依赖项。依赖项通常是您在应用程序中使用的 NuGet 包。
dotnet build 生成您的代码! 此命令将生成适用于您的项目的中间语言 (IL) 二进制。如果项目是控制台应用程序,则产生的输出是可执行的,您可以立即运行。默认情况下,生成命令会将生成的程序集和可执行文件(如果适用)输出到调用位置目录的 bin 目录中。
dotnet test 如果不支持运行测试,则不会出现适合的工具。此命令让您可以使用在 project.json 文件中指定的运行程序运行一组测试。目前支持 xUnit 和 NUnit 测试运行程序。
dotnet publish 发布在目标计算机上运行的应用程序。
dotnet pack pack 命令会把您的项目打包成 NuGet 包。输出一组 nupkg 文件后,您可以将其上载至您的源,或使用本地文件夹替代将其用于还原操作。
dotnet run 运行命令将编译并运行您的应用程序。您可以将其看作没有 Visual Studio 的 Ctrl+F5 模拟。

除带有包的命令外,您还具有将其他命令添加为 project.json 中的工具并将其还原的选项。它们被打包为 NuGet 包,可提供适合且易用使用和理解的扩展性模型。

总结

希望您已经了解了 .NET Core 的相关知识,并乐于编写可以跨平台运行的 .NET 代码。作为一个新的堆栈,它会提供一些令人兴奋的功能,这在之前的 .NET Framework 上是不可能具备的。.NET CLI 还引入了绝佳的命令行体验,这将成为开发人员体验的基础,并可集成入 Visual Studio 和 Visual Studio Code 等其他工具。

最后,我们了解您有多种针对 .NET Framework 编写的资产,我们很乐于看到这些资产随着 .NET Framework 的演变不断发展。设想一个这样的世界:在一个系统中一起使用 .NET Framework 和 .NET Core,并利用两个堆栈的优势。

如果您想了解更多并参与其中,您可以从以下网站开始:

我们还有很多其他正在开发的 .NET 开源项目。如果您想看到更多内容,请查看 .NET Foundation,这是一个促进 .NET 开源开发和合作的独立组织。Microsoft 已经为 .NET Foundation 以及其他公司(例如 Xamarin、Umbraco、Salesforce 和 .NET 社区)贡献了多个项目。了解项目的详细内容及其贡献,请前往 DotNetFoundation.org/projects


Phillip Carter是 Microsoft .NET 团队的一名项目经理。作为系统和编程语言理论的爱好者,Carter 经常熬夜与友人争论并发模型。他希望有一天可以在类型系统中表示所有系统的运行时行为,从而使人类能够快速地上升到更高的推论状态。可通过 phcart@microsoft.com 与他联系。

Zlatko Knezevic是 Microsoft .NET 团队的一名项目经理 (PM)。他于 2005 年加入 Microsoft,首先在 CEE 担任开发推广人员,然后又前往 SQL Server 担任 PM。在那里,他承担多种工作,不仅要向核心引擎添加新索引,还要生成处理大数据、数据发现等内容的对接服务。2015 年,他加入 .NET 团队担任 PM,并一直从事 .NET Core 跨平台体验方面的工作。可通过 Zlatko.Knezevic@microsoft.com 与他联系。

衷心感谢以下 Microsoft 技术专家对本文的审阅: Immo Landwerth 和 .NET Core 与 Framework 项目管理团队