.NET Core 简单介绍

.NET Core 入门

.NET Core 可以在 WindowsLinuxmacOS/OS X 上运行。

Windows

Windows 上安装 .NET Core。

Linux

Linux 上安装 .NET Core。

OS X/macOS

安装适用于 macOS 的 .NET Core。 .NET Core 可在 OS X El Capitan(版本 10.11)和 macOS Sierra(版本 10.12)上使用。

.NET 体系结构组件

.NET 应用开发用于并运行于一个或多个 .NET 实现。 .NET 实现包括 .NET Framework、.NET Core 和 Mono。 .NET 的所有实现都有一个名为 .NET Standard 的通用 API 规范。 本文简要介绍了每个概念。

.NET Standard

.NET Standard 是一组由 .NET 实现的基类库实现的 API。 更正式地说,它是构成协定统一集(这些协定是编写代码的依据)的特定 .NET API 组。 这些协定在每个 .NET 实现中实现。 这可实现不同 .NET 实现间的可移植性,有效地使代码可在任何位置运行。

.NET Standard 也是一个目标框架。 如果代码面向 .NET Standard 版本,则它可在支持该 .NET Standard 版本的任何 .NET 实现上运行。

.NET 实现

.NET 的每个实现都具有以下组件:

  • 一个或多个运行时。 示例:用于 .NET Framework 的 CLR、CoreCLR 和用于 .NET Core 的 CoreRT。
  • 实现 .NET Standard 并且可实现其他 API 的类库。 示例:.NET Framework 基类库、.NET Core 基类库。
  • 可选择包含一个或多个应用程序框架。 示例: ASP.NET、Windows 窗体和 Windows Presentation Foundation (WPF) 包含在 .NET Framework 中。
  • 可包含开发工具。 某些开发工具在多个实现之间共享。

Microsoft 积极开发和维护的主要 .NET 实现有 4 个:.NET Core、.NET Framework、Mono 和 UWP。

.NET Core

.NET Core 是 .NET 的跨平台实现,专用于处理大规模的服务器和云工作负荷。 可在 Windows、macOS 和 Linux 上运行。 它实现 .NET Standard,因此面向 .NET Standard 的代码都可在 .NET Core 上运行。 ASP.NET Core 在 .NET Core 上运行。

.NET Framework

.Net Framework 是自 2002 年起就已存在的原始 .NET 实现。 它是当前 .NET 开发人员经常使用的 .NET Framework。 4.5 版以及更高版本实现 .NET Standard,因此面向 .NET Standard 的代码都可在这些版本的 .NET Framework 上运行。 它还包含一些特定于 Windows 的 API,如通过 Windows 窗体和 WPF 进行 Windows 桌面开发的 API。 .NET Framework 非常适合用于生成 Windows 桌面应用程序。

Mono

Mono 是主要在需要小型运行时使用的 .NET 实现。 它是在 Android、Mac、iOS、tvOS 和 watchOS 上驱动 Xamarin 应用程序的运行时,且主要针对小内存占用。 Mono 还支持使用 Unity 引擎生成的游戏。

它支持所有当前已发布的 .NET Standard 版本。

以前,Mono 实现更大的 .NET Framework API 并模拟一些 Unix 上最常用的功能。 有时使用它运行依赖 Unix 上的这些功能的 .NET 应用程序。

Mono 通常与实时编译器一起使用,但它也提供在 iOS 之类的平台使用的完整静态编译器(预先编译)。

通用 Windows 平台 (UWP)

UWP 是用于为物联网 (IoT) 生成新式触控 Windows 应用程序和软件的 .NET 实现。 它旨在统一可能想要以其为目标的不同类型的设备,包括电脑、平板电脑、平板手机、电话,甚至 Xbox。 UWP 提供许多服务,如集中式应用商店、执行环境 (AppContainer) 和一组 Windows API(用于代替 Win32 (WinRT))。 应用可采用 C++、C#、VB.NET 和 JavaScript 编写。 使用 C# 和 VB.NET 时,.NET API 由 .NET Core 提供。

.NET 运行时

运行时是用于托管程序的执行环境。 OS 属于运行时环境,但不属于 .NET 运行时。 下面是 .NET 运行时的一些示例:

  • .NET Framework 公共语言运行时 (CLR)
  • .NET Core 核心公共语言运行时 (CoreCLR)
  • 适用于通用 Windows 平台的 .NET Native
  • 用于 Xamarin.iOS、Xamarin.Android、Xamarin.Mac 和 Mono 桌面框架的 Mono 运行时

.NET 工具和常见基础结构

可访问一整套适用于每种 .NET 实现的工具和基础结构组件。 包括(但不限于)以下几种:

  • .NET 语言及其编译器
  • .NET 项目系统(基于 .csproj.vbproj 和 .fsproj 文件)
  • MSBuild(用于生成项目的生成引擎)
  • NuGet(适用于.NET 的 Microsoft 程序包管理器)
  • 开放源生成业务流程工具,例如 CAKEFAKE

包、元包和框架

.NET Core 是一种由 NuGet 包组成的平台。 有些产品体验受益于包的细粒度定义,而另一些受益于粗粒度的定义。 为了适应这种二元定义,一款好的产品应该作为一组细粒度的包发布,然后在更粗的粒度组块中进行描述,单个包的正式的名字叫做“元包”。

每个 .Net Core 包都支持以框架形式通过多个 .Net 实现代码运行。 其中有些框架是传统框架,例如表示 .NET Framework 的 net46。 而另一些则是新框架,可视为是“基于包的框架”,这种是框架的另外一种新的定义模型。 这些基于包的框架整个都是由包组成的,它们自身也被定义成包,这就在包与框架之间形成了一种比较密切的关系。

.NET Core 被分成一组包,它们提供了基元类型,以及更高层的数据类型,应用组合类型和通用实用工具。 每一个包都代表着单独的同名程序集。 例如,System.Runtime 这个包就包含了 System.Runtime.dll 程序集。

以细粒度方式定义这些包具有以下好处:

  • 细粒度的包可以在它自己的计划内交付,只需完成仅对相关的其他有限的包进行测试即可。
  • 细粒度的包可以提供不同的 OS 和 CPU 支持。
  • 细粒度的包可以单独依赖于某一个库。
  • 应用可以变得更小,因为没有引用的包不会变成应用发行的一部分。

上述某些好处只适用于某些特定场合。 例如,.NET Core 的所有包通常都会在同一计划内提供对同一平台的支持。 在这种情况下,补丁与更新会以小的单独包的形式发布和安装。 由于这种小范围的变化,补丁的验证与时间花费,都可以限制到单个库的需求范围中。

以下是 .NET Core 重要的 NuGet 包列表:

  • System.Runtime - 最基础的 .NET Core 包,包括
  • System.Collections - 一组(主要)泛型集合,包括
  • System.Net.Http - 一组用于 HTTP 网络通信的类型,包括
  • System.IO.FileSystem - 一组用于读写到本地或网络磁盘存储的类型,包括
  • System.Linq - 一组用于查询对象的类型,包括 Enumerable
  • System.Reflection - 一组用于加载、检查和激活类型的类型,包括

通常情况下,相较于逐个地将包包含在项目中,包含元包会简单得多,元包是指通常配合在一起使用的一组包。 (有关元包的更多信息,请参见下一部分。)但是当需要单个包时,可以按以下示例所示的那样来包含它,此示例引用 System.Runtime 包。

1
2
3
4
5
6
7
8
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Runtime" Version="4.3.0" />
</ItemGroup>
</Project>

元包

元包就是一个 NuGet 包约定,描述了一组意义相关的包。 开发团队利用依赖项来描述这一组包。 他们通过这一组包来描述一个框架,然后有选择地发布出去。

默认情况下,早期版本的 .NET Core 工具(同时基于 project.json 和 csproj 的工具)指定一个框架和一个元包。 但目前,由目标框架隐式引用元包,以便将每个元包绑定到一个目标框架。 例如,netstandard1.6 框架引用 NetStandard.Library 1.6.0 版元包。 同样, netcoreapp1.1 框架引用 Microsoft.NETCore.App 1.1.0 版元包。

以某个框架为目标以及隐式引用元包,这实际上是添加了对元包中每一个独立包的引用依赖。 这使这些包中的所有库都可用于 IntelliSense(或类似体验),同时也可用于发布应用。

使用元包具有以下好处:

  • 在引用大量细粒度包方面,提供了一种方便的用户体验。
  • 定义了一组经过充分测试且运行良好的包(包括指定的各种版本)。

.NET Standard 元包为:

  • NETStandard.Library - 描述了属于“.NET Standard”一部分的各种库。 适用于所有支持 .NET Standard 的 .NET 实现(例如,.NET Framework、.NET Core 和 Mono)。 也就是“netstandard”框架。

重要的 .NET Core 元包有:

框架

每个 .NET Core 包支持一组运行时框架。 框架描述了一组可用的 API(以及潜在的其他特性),所以你可以在指定一个目标框架时使用这些功能。 添加新的 API 时,它们就会进入版本控制流程。

例如,System.IO.FileSystem 支持以下框架:

  • .NETFramework,Version=4.6
  • .NETStandard,Version=1.3
  • 6 种 Xamarin 平台(例如,xamarinios10)

将前两个框架进行对比很有帮助,因为它们各自代表了一种不同的框架定义方式。

.NETFramework,Version=4.6 框架表示 .NET Framework 4.6 中可用的 API。 你可以生成使用 .NET Framework 4.6 引用程序集编译的库,并以NuGet 包的方式在 net46 lib 文件夹中发布这些库。 这样,你的库就会被那些基于或者兼容 .Net Framework 4.6 的应用所使用。 这是所有框架的传统工作原理。

.NETStandard,Version=1.3 框架是一个基于包的框架。 它依赖基于框架的包,来定义和公开与框架有关的 API。

基于包的框架

框架和包之间是一种双向关系。 首先是为一个给定的框架定义了 API,例如 netstandard1.3。 以 netstandard1.3 为目标的包(或兼容的框架,如 netstandard1.0)定义了适用于 netstandard1.3 的 API。 听起来像是循环定义,然而并不是。 从“基于包的”这个词本身的角度来讲,框架的 API 定义是来自于包的。 框架本身并不定义任何 API。

其次,是这个双向关系中的资产选择。 包可以包含多个框架的资产。 对于一组包和/或元包的引用,框架需要决定它应选择哪些资产,例如,是 net46 还是 netstandard1.3。 选择正确的资产很重要。 例如,net46 资产可能并不与 .NET Framework 4.0 或 .NET Core 1.0 兼容。

可以在下图中看到这种关系。 API 选择框架作为目标并定义了框架。 而框架用于资产选择资产实现了 API。

PNG

在 .Net Core 基础之上,基于包的框架主要有两个:

  • netstandard
  • netcoreapp

.NET Standard

.NET Standard(目标框架名字对象:netstandard)框架表示在 .NET Standard 基础之上生成并由其定义的 API。 如果构建的库将用于在多个运行时上运行,就应将此框架作为目标。 这样便可在任何一种兼容 .NET 标准的运行时上受支持,例如 .NET Core、.NET Framework 和 Mono/Xamarin。 每个运行时都支持一组 .NET Standard 版本,具体取决于实现的 API。

netstandard 框架隐式引用 NETStandard.Library 元包。 例如,以下 MSBuild 项目文件指示项目以 netstandard1.6 为目标,其引用 NETStandard.Library 1.6 版元包。

1
2
3
4
5
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
</Project>

但项目文件中的框架和元包引用不需要匹配,并且可使用项目文件中的 <NetStandardImplicitPackageVersion> 元素指定低于元包版本的框架版本。 例如,以下项目文件有效。

1
2
3
4
5
6
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
<NetStandardImplicitPackageVersion>1.6.0</NetStandardImplicitPackageVersion>
</PropertyGroup>
</Project>

面向 netstandard1.3 却使用 NETStandard.Library 1.6.0 版本,这一点很奇怪。 然而,这是一个有效的用例,因为元包支持更旧的 netstandard 版本。 可能恰好你已将 1.6.0 版的元包进行了标准化,然后将其用于所有库,而这些库可以面向各种 netstandard 版本。 使用此方法,只需还原 NETStandard.Library 1.6.0,无需加载早期版本。

反之,把 netstandard1.6 设为目标,却使用 1.3.0 版的 NETStandard.Library 也是无效的。 你不能把更高版本的框架设为目标,却使用更低版本的元包,因为更低版本的元包不会公开任何更高版本框架的资产。 元包资产的版本控制方案与描述框架的最高版本匹配。 借助于版本控制方案,NETStandard.Library 的第一个版本是 v1.6.0,因为它包含 netstandard1.6 资产。 而上例中的 v1.3.0 版本,只是为了举例方便,实际上并不存在。

.NET Core 应用程序

.NET Core 应用程序 (TFM: netcoreapp) 框架表示 .NET Core 发行版及其提供的控制台应用程序模型附带的包和相关 API。 .NET Core 必须使用此框架,因为必须要使用其中的控制台应用程序模型。同时只运行于 .Net Core 平台的库也应使用此模型。 使用此框架后,所有应用和库将只能够在 .Net Core 上运行。

Microsoft.NETCore.App 元包的目标框架是 netcoreapp。 它提供了约 60 个库的访问权限,其中约 40 个由 NETStandard.Library 包提供,还有另外 20 个库。 可以引用目标框架为 netcoreapp 或与框架(如 netstandard)兼容的库获得对其他 API 的访问权限。

Microsoft.NETCore.App 提供的大部分其他库还可以使用 netstandard 作为目标,如果其他 netstandard 库满足这些框架的依赖项的话。 这意味着,netstandard 库也可以引用这些包作为依赖项。

×

谢谢你请我吃辣条

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. .NET Core 入门
    1. 1.1. Windows
    2. 1.2. Linux
    3. 1.3. OS X/macOS
  2. 2. .NET 体系结构组件
    1. 2.1. .NET Standard
    2. 2.2. .NET 实现
      1. 2.2.1. .NET Core
      2. 2.2.2. .NET Framework
      3. 2.2.3. Mono
      4. 2.2.4. 通用 Windows 平台 (UWP)
    3. 2.3. .NET 运行时
    4. 2.4. .NET 工具和常见基础结构
  3. 3. 包、元包和框架
    1. 3.1.
    2. 3.2. 元包
    3. 3.3. 框架
    4. 3.4. 基于包的框架
      1. 3.4.1. .NET Standard
      2. 3.4.2. .NET Core 应用程序
,