Dotnet Core 简明教程
.NET Core - Overview
在本教程中,我们涵盖了 .NET Core 和几项创新,包括 .NET Framework 更新、.NET Standard、通用 Windows 平台更新等。
Characteristics of .NET Core
以下是 .NET Core 的主要特征:
Open source
-
.NET Core is an open source implementation, using MIT and Apache 2 licenses.
-
.NET Core is a .NET Foundation project and is available on GitHub.
-
作为一个开源项目,它促进了更透明的开发过程,促进了积极且敬业的社区。
Cross-platform
-
无论您的平台目标如何,都可以在 .NET Core 中实现的应用程序,并且可以重用其代码。
-
它目前支持三种主要操作系统 (OS) Windows Linux MacOS
-
受支持的操作系统 (OS)、CPU 和应用程序场景将随着时间的推移而增加,由 Microsoft、其他公司和个人提供。
Flexible deployment
-
.NET Core 应用程序可以有两种类型的部署:依赖于框架的部署 自包含部署
-
使用框架依赖性部署时,您的应用程序依赖于安装您的应用程序和第三方依赖项的 .NET Core 的系统范围版本。
-
使用自包含部署时,用于构建应用程序的 .NET Core 版本也随应用程序和第三方依赖项一起部署,并且可以与其他版本并行运行。
Compatible
-
.NET Core is compatible with .NET Framework, Xamarin and Mono, via the .NET Standard Library
Modular
-
.NET Core is released through NuGet in smaller assembly packages.
-
.NET Framework is one large assembly that contains most of the core functionalities.
-
.NET Core is made available as smaller feature-centric packages.
-
这种模块化方式让开发人员将只有其应用程序中需要的 NuGet 包包含进来,从而对应用程序进行优化。
-
缩小应用程序表面积的好处包括更严格的安全、更少的维护、更高的性能以及按使用付费模式下的更低成本。
The .NET Core Platform
-
.NET Runtime − 它提供了一个类型系统、程序集加载、一个垃圾收集器、本机互操作以及其他一些基本服务。
-
Fundamental Libraries − 一组框架库,其中提供了基本数据类型、应用程序组件类型和基本实用程序。
-
SDK & Compiler − 一组 SDK 工具和语言编译器,其中包含在 .NET Core SDK 中,可用于基本开发人员体验。
-
‘dotnet’ app host − 它用于启动 .NET Core 应用程序。它选择运行时并托管运行时,提供程序集加载策略并启动应用程序。相同的主机还可以以大体相同的方式用于启动 SDK 工具。
.NET Core - Prerequisites
在本章中,我们将讨论在部署和运行时您需要存在的各种依赖关系。其中包括在 Windows 机器上使用 Visual Studio 开发的 .NET Core 应用程序。
Supported Windows Versions
-
Windows 7 SP1
-
Windows 8.1
-
Windows 10
-
Windows Server 2008 R2 SP1(完整版服务器或 Server Core)
-
Windows Server 2012 SP1(完整版服务器或 Server Core)
-
Windows Server 2012 R2 SP1(完整服务器或服务器核心)
-
Windows Server 2016(完整服务器、服务器核心或 Nano Server)
Dependencies
-
如果您在早于 Windows 10 和 Windows Server 2016 的 Windows 版本上运行您的 .NET Core 应用程序,则还需要 Visual C++ Redistributable。
-
如果您使用 .NET Core 安装程序,此依赖项将自动为您安装。
-
如果您通过安装脚本安装 .NET Core 或部署自包含的 .NET Core 应用程序,则需要手动安装 Visual Studio 2015 的 Visual C++ Redistributable。
-
对于 Windows 7 和 Windows Server 2008 机器,您需要确保您的 Windows 安装是最新版本,并且还通过 Windows 更新安装了修补程序 KB2533623。
.NET Core - Environment Setup
在本章中,我们将讨论 .NET Core 的环境设置。它对 .NET Framework 进行了重大重新设计。要在您的应用程序中使用 .NET Core,您可以使用两个版本:
-
Visual Studio 2015
-
Visual Studio 2017 RC
Visual Studio 2015
要使用 Visual Studio 2015,您必须安装以下内容:
-
Microsoft Visual Studio 2015 Update 3
-
Microsoft .NET Core 1.0.1 - VS 2015 Tooling Preview 2
Microsoft 提供了一个visual studio的免费版本,其中还包含 SQL Server,可以从 https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx 下载,而 Microsoft .NET Core 1.0.1 - VS 2015 Tooling Preview 2可以从 https://www.visualstudio.com/downloads/ 下载
你也可以在以下网址上查看安装指南 https://www.microsoft.com/net/core/#windowsvs2017
Installation of Visual Studio 2015
按照以下步骤安装 Visual Studio 2015:
Step 1 - 下载完成后,运行安装程序。将显示以下对话框。
Step 2 - 单击 Install 以开始安装过程。
Step 3 - 安装完成后,您将看到以下对话框。
Step 4 - 关闭此对话框并在需要时重新启动计算机。
Step 5 - 从“开始”菜单中打开 Visual Studio;你将收到以下对话框。首次加载并最终使用可能需要几分钟。
Step 6 - 加载后,你将看到以下屏幕。
Step 7 - Visual Studio 安装完成后,关闭 Visual Studio 并启动 Microsoft .NET Core - VS 2015 Tooling Preview 2。
Step 8 − 勾选复选框,然后单击安装。
Step 9 - 安装完成后,你将看到以下对话框。
你现在已可以使用 .NET Core 启动应用程序。
Visual Studio 2017
在本教程中,我们将使用 Visual Studio 2015,但如果你想使用 Visual Studio 2017,Visual Studio 2017 RC 中包括一个 Visual Studio 的 .NET Core 工具试用版,你可以在这里查看安装指南 https://www.microsoft.com/net/core/#windowsvs2017
.NET Core - Getting Started
Visual Studio 2015 为 .NET Core 应用程序开发提供了一个全功能的开发环境。在本章中,我们将在 Visual Studio 中创建一个新项目。安装 Visual Studio 2015 工具后,便可开始构建新的 .NET Core 应用程序。
在 New Project 对话框中,在“模板”列表中,展开 Visual C# 节点并选择 .NET Core,你应该会看到以下三个新项目模板
-
Class Library (.NET Core)
-
Console Application (.NET Core)
-
ASP.NET Core Web 应用程序(.NET Core)
在“新建项目”对话框的中间窗格中,选择“控制台应用程序(.NET Core)”,并将其命名为“FirstApp”,然后单击“确定”。
Visual Studio 将打开新创建的项目,你将在“解决方案资源管理器”窗口中看到此项目中的所有文件。
要测试 .NET Core 控制台应用程序是否正常运行,我们添加以下行。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace FirstApp {
public class Program {
public static void Main(string[] args) {
Console.WriteLine("Hello guys, welcome to .NET Core world!");
}
}
}
现在,运行该应用程序。你应看到以下输出。
.NET Core - Numerics
-
System.Numerics.BigInteger 这是一个不带上下限的整数类型。
-
System.Numerics.Complex 这是一个表示复数的类型。
-
System.Numerics 命名空间中的单指令多数据 (SIMD) 启用向量类型的集合。
Integral types
下表表示整数类型及其大小;
Type |
Signed/ Unsigned |
Size (bytes) |
Minimum Value |
Maximum Value |
Byte |
Unsigned |
1 |
0 |
255 |
Int16 |
Signed |
2 |
−32,768 |
32,767 |
Int32 |
Signed |
4 |
−2,147,483,648 |
2,147,483,647 |
Int64 |
Signed |
8 |
−9,223,372,036,854,775,808 |
9,223,372,036,854,775,807 |
SByte |
Signed |
1 |
-128 |
127 |
UInt16 |
Unsigned |
2 |
0 |
65,535 |
UInt32 |
Unsigned |
4 |
0 |
4,294,967,295 |
UInt64 |
Unsigned |
8 |
0 |
18,446,744,073,709,551,615 |
每种整数类型都支持一组标准术语,包括算术、比较、相等性、显式转换和隐式转换运算符。
你还可以使用 System.BitConverter 类通过整数值中的单独位进行操作。
Floating-point types
Type |
Size (bytes) |
Minimum Value |
Maximum Value |
Double |
8 |
−1.79769313486232e308 |
1.79769313486232e308 |
Single |
4 |
−3.402823e38 |
3.402823e38 |
Decimal |
16 |
−79,228,162,514,264,337,593,5 43,950,335 |
79,228,162,514,264,337,593,543,9 50,335 |
-
每个浮点类型都支持一组标准算术、比较、相等、显式转换和隐式转换运算符。
-
你还可以通过使用 BitConverter 类来处理 Double 和 Single 值中的各个位。
-
Decimal 结构具有自己的方法 Decimal.GetBits 和 Decimal.Decimal(Int32()),用于处理十进制值的各个位,以及用于执行一些附加数学运算的自己的方法集。
BigInteger
-
System.Numerics.BigInteger 是一个不可变类型,它表示一个理论上没有上限或下限的任意大整数。
-
BigInteger 类型的这些方法与其他整体类型的非常相似。
Complex
-
System.Numerics.Complex 类型的复合数即,一个具有实数部分和虚数部分的数
-
它支持一组标准的算术、比较、相等、显式转换和隐式转换运算符,以及数学、代数和三角函数方法。
SIMD
-
Numerics 命名空间包括一组针对 .NET Core 的 SIMD 矢量类型。
-
SIMD 允许在硬件级别并行执行一些操作,从而显著提高针对矢量执行计算的数学、科学和图形应用程序的性能。
-
.NET Core 中的 SIMD 矢量类型包括以下内容:-System.Numerics.Vector2、System.Numerics.Vector3 和 System.Numerics.Vector4 类型,分别为 2、3 和 4 维度的 Single 类型矢量。Vector<T> 结构,允许你创建一个任何基本数字类型的矢量。基本数字类型包括 System 命名空间中的所有数字类型,十进制数除外。两种矩阵类型,System.Numerics.Matrix3X2,它表示一个 3×2 矩阵;System.Numerics.Matrix4X4,它表示一个 4×4 矩阵。System.Numerics.Plane 类型,它表示一个三维平面;System.Numerics.Quaternion 类型,它表示一个矢量,用于对三维物理旋转进行编码。
.NET Core - Garbage Collection
在本章中,我们将介绍垃圾回收的概念,它是 .NET 托管代码平台最重要的特性之一。垃圾回收器 (GC) 管理着内存的分配和释放。垃圾回收器充当自动内存管理器。
-
你无需了解如何分配和释放内存或管理使用该内存的对象的生命周期
-
在使用“new”关键字声明对象或对值类型进行装箱时,将进行分配。分配通常非常快。
-
当没有足够的内存来分配一个对象时,GC 必须回收和处置垃圾内存,以便为新的分配提供内存。
-
此过程称为 garbage collection 。
Advantages of Garbage Collection
垃圾回收提供了以下好处:
-
在开发应用程序时,你无需手动释放内存。
-
它还高效地在托管堆上分配对象。
-
当对象不再使用时,它将回收那些对象,清除它们的内存,并让内存供以后分配使用。
-
受管对象自动获取干净内容以开始执行,因此它们的构造函数不必初始化每个数据字段。
-
它还通过确保对象无法使用另一个对象的内容实现内存安全。
Conditions for Garbage Collection
如果下列条件之一为真,则发生垃圾回收。
-
系统物理内存较低。
-
受管堆上已分配对象使用的内存超过了可接受的阈值。在进程运行过程中,该阈值会不断地进行调整。
-
调用的 GC.Collect 方法,而且在几乎所有情况下,你都无需调用该方法,因为垃圾回收程序会不断运行。此方法主要用于特殊情况和测试中。
Generations
Generation First (0)
-
在第 0 代中,首先分配对象。
-
在这一代中,由于在下次垃圾回收发生时不再使用对象(超出范围),因此对象常常不会存活超过第一代。
-
由于其关联堆较小,因此第 0 代可快速进行回收。
Generation Second (1)
-
在第 1 代中,对象享有第二次机会。
-
存活期较短,但是又能够经历第 0 代回收的对象(常常与巧合的时间点有关),会进入第 1 代。
-
第 1 代的回收也较快,因为其关联堆同样较小。
-
前两个堆保持较小,其原因是对象会受到回收或被提升到下一代堆。
Generation Third (2)
-
在第 2 代中,所有长寿命对象都会存活,并且其堆会增长得很大。
-
这一代中的对象会存活很长时间,而且没有下一代堆可以进一步提升对象。
-
垃圾回收程序拥有一个用于大型对象的其他堆,称为大型对象堆 (LOH)。
-
该堆专门针对大小为 85,000 字节或更大的对象而保留。
-
不会将大型对象分配到代堆,而是直接分配到 LOH 中
-
对于长期运行或对大量数据进行操作的程序,生成 2 和 LOH 集合可能需要显着的时间。
-
众所周知,大型服务器程序的堆内存有几十 GB。
-
垃圾回收器采用了多种技术来减少其阻止程序执行的时间量。
-
主要方法是在后台线程上尽可能多地执行垃圾回收工作,而不会干扰程序执行。
-
垃圾回收器还暴露出一些方式供开发人员影响其行为,这对于提高性能非常有用。
.NET Core - Code Execution
在本章中,我们将了解 .NET Core 的执行过程并将其与 .NET Framework 进行比较。托管执行过程包括以下步骤。
-
Choosing a compiler
-
将您的代码编译为 MSIL
-
将 MSIL 编译为本机代码
-
Running code
Compiling your code to MSIL
-
编译会将您的源代码翻译成 Microsoft 中间语言 (MSIL) 并生成所需的元数据。
-
元数据描述代码中的类型,包括每个类型的定义、每个类型成员的签名、代码引用的成员,以及在执行时运行时所用的其他数据。
-
在执行期间,运行时会根据需要从文件以及框架类库 (FCL) 中查找和提取元数据。
Compiling MSIL to Native Code
-
在执行时,即时 (JIT) 编译器会将 MSIL 翻译成本机代码。
-
在此编译过程中,代码必须通过一个验证过程,该过程会检查 MSIL 和元数据以找出能否确定代码是类型安全的。
Running Code
-
公共语言运行时提供了使执行得以发生的基础架构,以及可以在执行期间使用的服务。
-
在执行过程中,托管代码会收到服务,如垃圾回收、安全性、与非托管代码的互操作性、跨语言调试支持,以及增强的部署和版本控制支持。
.NET Core Code Execution Process
现在让我们关联一下使用 .NET Framework 和 .NET Core 来执行代码的方法。在 .NET Core 中,有这些组件的许多替代品,这些组件是 .NET Framework 的一部分。
-
在 .NET Core 中,我们现在有了一系列新的编译器,比如 C# 和 VB 的 Roslyn。
-
如果你想使用 F# 与 .NET Core,那你还可以利用新的 F# 4.1 编译器。
-
实际上,这些工具是不同的,如果我们使用的是 C# 6 或更高版本,那我们也可以将 Roslyn 与 .NET Framework 结合使用,因为 C# 编译器只能支持至 C# 5。
-
在 .NET Core 中,我们没有框架类库(FCL),因此会使用一组不同的库,而我们现在有了 CoreFx。
-
CoreFx 是面向 .NET Core 的类库的重新实现。
-
我们还拥有一个新的运行时,即 .NET Core,被称为 CoreCLR 并且利用 JIT 编译器。
-
现在的问题在于,我们为什么要重新实现 .NET 框架中已经拥有的所有这些组件。
-
因此答案与 Microsoft 为何要实现 .NET Core 相同。
.NET Core - Modularity
这是 .NET Core 构建和实现模块化应用程序的另一个考虑因素。你的应用程序现在可以仅安装必需的内容,而不是安装整个 .NET Framework。我们转到 Visual Studio 并查看模块化性。
这是我们在解决方案资源管理器中的简单 .NET Core 应用程序。让我们展开“引用”,你将看到对 .NETCoreApp 的引用。
在 .NETCoreApp 中,你将看到对 NuGet 的程序包引用;我们展开它。
你将看到一整套 NuGet 程序包引用。如果你使用过 .NET Framework,那么这些命名空间中的许多将会看起来很熟悉,因为你习惯于在 .NET Framework 中使用它。
-
现在,如果你展开 NETStandard.Library,你将看到其他引用。你甚至会注意到 System.Console,我们正在这个应用程序中使用它。
-
现在你不必引入 .NET Framework 中的所有内容,而只需要引入应用程序所需的即可。
-
还有一些其他好处;例如,根据需要,这些模块可以单独更新。
模块化具有性能优势,并且你的应用程序可以更快地运行,尤其是 ASP.NET Core 应用程序。
.NET Core - Project Files
在本章中,我们将讨论 .NET Core 项目文件以及如何在项目中添加现有文件。
让我们理解一个简单的例子。在该示例中,我们有某些已经创建的文件;我们必须在 FirstApp 项目中添加这些文件。
以下是 Student.cs 文件的实现。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace FirstApp {
public class Student {
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
}
}
以下是 Course.cs 文件的实现。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace FirstApp {
public class Course {
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
}
}
现在让我们在磁盘和项目的源文件夹中保存这三个文件。
-
如果你熟悉 .NET,并且这是一个传统的 .NET 框架控制台应用程序,那么了解如何在 Visual Studio 中向项目中添加这些文件非常重要。
-
你首先需要将这些文件拖动到解决方案资源管理器中,以便将它们复制到项目文件夹中,因为你的项目需要引用这些文件。
-
.NET Core 的优点之一是处理项目文件的(project.json),我们可以将文件直接放入到项目的根目录,然后这些文件会被自动包含在我们的项目中。
-
我们不必像过去为传统的 .NET Framework 应用程序在 Visual Studio 中所做的那样手动引用文件。
现在打开你的项目根目录。
将所有三个文件复制到项目根目录。
你可以在根文件夹中看到所有复制的文件。
现在转到 Visual Studio,你会收到以下对话框。
单击 Yes to All 重新加载你的项目。
现在,文件会被自动包含在你的项目中。
.NET Core - Package References
在本章中,我们将讨论如何在 .NET Core 应用程序中添加包以及如何查找特定的包。我们可以直接转到 NuGet 并添加包,不过我们将在其他一些地方看到。
现在让我们转到 .NET Core 的源代码,其位于此处 - https://github.com/dotnet/corefx
在 CoreFx 存储库中,打开 src 文件夹 -
你将看到一整套与不同程序包相对应的文件夹。我们现在搜索 Json -
有一种方法可以查找软件包,如果您熟悉 .NET Framework,可能知道各种类型,但是 .NET Core 中的软件包组装完全不同,您不知道其中的软件包位于何处。
如果您知道类型,您可以使用 https://packagesearch.azurewebsites.net/ 搜索反向软件包搜索
在此处,您可以输入希望查找的任何类型的软件包。然后,此站点将扫描 NuGet 并为您找到相关软件包。
现在让我们搜索 DataContractJson 。
您现在会看到,我们得到了相同的软件包;让我们单击软件包。
您现在将看到 NuGet 页面;您需要确认需要此软件包。可以使用一些方法在应用程序中添加此软件包。
让我们打开 project.json 文件。
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {
"imports": "dnxcore50"
}
}
}
这是新的项目格式,此文件内将看到依赖项部分。让我们如下所示添加新的依赖项。
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
},
"System.Runtime.Serialization.Json": "4.0.2"
},
"frameworks": {
"netcoreapp1.0": {
"imports": "dnxcore50"
}
}
}
现在,如果您查看引用,您将看到 System.Runtime.Serialization.Json 软件包添加到项目中。
另一种方式是转到 NuGet Manager 并浏览您要添加的软件包。
.NET Core - Create UWP App
在本章中,我们将讨论如何使用 .NET Core 创建 UWP 应用程序。UWP 也称为 Windows 10 UWP 应用程序。此应用程序不适用于以前版本的 Windows,只会适用于将来的 Windows 版本。
以下是 UWP 将顺畅运行的一些例外情况。
-
如果你想在本地运行它,则必须使用 Windows 10,你也可以在 Windows 8 上进行开发,然后需要在模拟器上运行它,但我们鼓励使用 Windows 10。
-
对于 UWP 应用程序,你将还需要 Windows 10 SDK。让我们打开 Visual Studio 2015 设置,然后修改 Visual Studio。
-
在“选择功能”页面上,向下滚动,你会看到通用 Windows 应用开发工具,选中该选项,如下所示。
在这里,你可以看到 SDK 的不同版本以及工具的最新更新,单击“下一步”。
现在,单击 Install 按钮。
安装完成后需要重新启动系统。
现在,让我们按照以下步骤实现 UWP。
-
首先,启动 Visual Studio 2015。
-
点击“文件”菜单并选择“新建 → 项目”;这将弹出一个“新建项目”对话框。可以在对话框的左窗格中看到不同类型的模板。
-
在左窗格中,可以看到树形视图。现在从“模板 → Visual C# → Windows”中选择通用模板。
-
从中间窗格中,选择空白应用(通用 Windows)模板。
-
在“名称”字段中输入 UWPFirstApp 来给项目命名,然后点击“确定”。
-
将出现目标版本/最低版本对话框。默认设置适用于本教程,因此选择“确定”创建项目。
-
这里,我们有一个可以针对所有 Windows 10 设备的单个项目。你会注意到 .NET Core 和 UWP 使得多重定位变得简单。
-
新项目打开时,它的文件显示在“解决方案资源管理器”窗格的右侧。可能需要选择“解决方案资源管理器”选项卡,而不是“属性”选项卡才能看到文件。
-
尽管空白应用(通用 Windows)是一个最简单的模板,但它仍然包含很多文件。这些文件对于使用 C# 的所有 UWP 应用都是必备的。在 Visual Studio 中创建的所有项目都包含这些文件。
-
为了看到正在运行的示例,让我们打开 MainPage.XAML 并在其中增加以下代码。
<Page
x:Class = "UWPFirstApp.MainPage"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local = "using:UWPFirstApp"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable = "d">
<Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel HorizontalAlignment = "Center">
<TextBlock Text = "Hello, world!"
Margin = "20"
Width = "200"
HorizontalAlignment = "Left"/>
<TextBlock Text = "Write your name."
Margin = "20"
Width = "200"
HorizontalAlignment = "Left"/>
<TextBox x:Name = "txtbox"
Width = "280"
Margin = "20"
HorizontalAlignment = "Left"/>
<Button x:Name = "button" Content = "Click Me"
Margin = "20"
Click = "button_Click"/>
<TextBlock x:Name = "txtblock"
HorizontalAlignment = "Left"
Margin = "20"/>
</StackPanel>
</Grid>
</Page>
以下是 C# 中按钮的单击事件。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at
// http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace UWPHellowWorld {
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page {
public MainPage() {
this.InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e) {
if (txtbox.Text != "")
txtblock.Text = "Hello: " + txtbox.Text;
else
txtblock.Text = "You have not write your name";
}
}
}
现在让我们在本地机器上运行以上代码,你将看到以下窗口。现在在文本框中输入任意名称,然后按下 Click Me 按钮。
.NET Core - MSBuild
在本章中,我们将讨论什么是 MSBuild,以及如何使用 .NET Core。MSBuild 是 Microsoft 和 Visual Studio 的构建平台。在 UWP 应用程序中,如果您打开项目文件夹,您将看到 project.json 和 *.csproj 文件。
但是,如果您打开我们以前的 .NET Core 控制台应用程序,您将看到 project.json 和 *.xproj 文件。
-
.NET Core 构建系统或 project.json 构建系统不足以满足 UWP 需求;这就是 UWP 仍然使用 *.csproj (MSBuild) 构建系统的原因。
-
但是 project.json 将在构建系统方面迁出。
-
现在,如果您希望在 UWP 应用程序中添加一些现有文件,就像我们在控制台应用程序中添加的那样,您需要在项目文件夹中添加那些文件。另外,您还需要将其包括在解决方案资源管理器中。
现在,让我们考虑以下文件;将这些文件复制到您的项目文件夹。
让我们回到 Visual Studio 并打开解决方案资源管理器。
-
您现在可以看到,在 UWP 应用程序中,仅复制文件还不够,因为在解决方案资源管理器中,我们看不到这些文件。
-
现在,我们还必须通过单击上文中突出显示的 Show All Files 图标包含这些文件,然后您将看到项目文件夹中的所有文件。
这两个文件仍然未 включены в наш проект. Чтобы включить эти файлы, выберите эти файлы, щелкните правой кнопкой мыши по любому файлу, а затем выберите Include in Project .
Теперь эти файлы также включены. Одним из преимуществ, которое можно предвидеть, является подход project.json к удалению файлов для *.csproj в будущей версии инструментов SKD, а также в Visual Studio.
.NET Core - Metapackage
В этой главе мы обсудим ссылки между нашим приложением Console и нашим приложением UWP. Если вы посмотрите на ссылки в обозревателе решений вашего приложения Console, вы увидите .NETCoreApp, как показано ниже.
-
Основная причина этого заключается в том, что здесь, в UWP, у нас есть *.csproj, поэтому мы возвращаемся к старому стилю ссылок, и мы можем ориентироваться только на один фреймворк с помощью этого типа проекта.
-
Однако ссылки похожи. Теперь вы можете видеть, что в приложении UWP ссылка на пакет NuGet Miscrosoft.NETCore.UniversalWindowsPlatform аналогична ссылке Microsoft.NETCore.App NuGet в приложении Console.
-
Как Miscrosoft.NETCore.UniversalWindowsPlatform, так и Microsoft.NETCore.App являются метапакетами, что означает, что они состоят из других пакетов.
-
В приложении Console мы можем углубиться и увидеть другие пакеты внутри Microsoft.NETCore.App, но мы не можем сделать то же самое с Miscrosoft.NETCore.UniversalWindowsPlatform в обозревателе решений.
-
Однако мы можем использовать другой инструмент, NuGet Package Explorer, чтобы посмотреть на это. Давайте теперь откроем этот URL-адрес в браузере - https://npe.codeplex.com/downloads/get/clickOnce/NuGetPackageExplorer.application , и вы увидите загрузку небольшой утилиты.
-
Как только загрузка будет завершена, дважды щелкните этот файл.
-
Нажмите Install , чтобы начать установку в проводнике пакетов NuGet.
-
После завершения установки вы увидите следующее диалоговое окно.
-
Теперь давайте нажмем на параметр Open a package from online feed .
-
По умолчанию он будет искать фид nuget.org. Давайте теперь найдем Microsoft.NETCore.UniversalWindowsPlatform в строке поиска, и вы увидите один результат, как показано ниже.
-
Нажмите на ссылку open , и она откроет зависимости верхнего уровня этого метапакета.
-
Теперь давайте откроем метапакет .NETCore для приложения .NETCore и метапакет для приложения UWP бок о бок.
-
Теперь вы можете видеть, что каждый метапакет состоит из разных наборов пакетов.
-
.NET Core is a subset of the classes available in .NET Framework at least at this point of time, but is growing and will be as per the base classes of .NET Framework.
-
UWP основан на .NET Core, это надмножество API, доступных для разработки в магазине Windows.
Теперь у нас есть больше API, доступных для разработки благодаря .NET Core.
Windows Runtime and Extension SDKs
Windows 运行时组件是自包含对象,你可以实例化并且能从任何语言使用,包括 C#、Visual Basic、JavaScript 和 C++。除了我们在上一章看到的 .NET Core 元包,UWP 应用程序默认还会引用通用的 Windows SDK。
通用 Windows 是对 Windows 运行时的引用,并且已分解成一系列 API 协定。
一个设备系列内的 API 集细分为称为 API 协定的子集。你可以在此处找到不同 API 协定的列表 https://msdn.microsoft.com/en-us/library/windows/apps/dn706135.aspx
大多数 Windows 运行时内的 API 都分解到了一个单一的协定中。我们现在在 API 协定页面上搜索 Universal 关键字。
你可以看到指向各种 API 的链接,你也可以看到 Universal 系列如此庞大,包括 12 页文档。
你也可以在此页面搜索电话 API 协定。
我们现在点击 Windows.Phone.PhoneContract 并向下滚动,你现在将看到电话或移动设备的电池信息。
如果你希望在你已经拥有的信息之上添加此信息,则应该手动添加引用。我们现在转到 Visual Studio,并且在解决方案资源管理器中右键单击引用。
选择 Add References…
你现在可以查看通用 Windows 的新引用类别,在此类别之下有 Core,它是指核心通用 Windows API 协定
-
扩展允许我们延伸功能,你将看到不同的引用,其中包括移动、桌面和其他扩展。
-
有不同的 SKD 扩展,并且你可以进一步添加以获取更多 API。
-
你还可以看到不同的版本。因此,请确保获取最新版本以获取已更新的 API,然后单击确定。
你现在可以看 Windows Mobile Extensions for the UWP 已作为引用添加。
.NET Core - Create .NET Standard Library
一个类库定义类型和方法,这些类型和方法可以从任何应用程序调用。
-
使用 .NET Core 开发的类库支持 .NET 标准库,这将允许你的库被支持该版本 .NET 标准库的任何 .NET 平台调用。
-
当你完成你的类库时,你可以决定是否要将它作为第三方组件分发,或者你是否希望将它作为与一个或多个应用程序捆绑在一起的组件包含在内。
让我们以在我们的控制台应用程序中添加一个类库项目作为开始,在解决方案资源管理器中右键单击 src 文件夹并且选择 Add → New Project…
在 Add New Project 对话框中选择 .NET Core 节点,然后选择类库(.NET Core)项目模板。
在“名称”文本框中,输入“UtilityLibrary”作为项目名称,如下图所示。
单击“确定”创建一个类库项目。在创建项目之后,我们添加一个新类。右键单击“解决方案资源管理器”中的 project 并选择 Add → Class…
在中间窗格中选择类并在“名称”和“字段”中输入StringLib.cs,然后单击 Add 。一旦添加了类,则替换StringLib.cs文件中的以下代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace UtilityLibrary {
public static class StringLib {
public static bool StartsWithUpper(this String str) {
if (String.IsNullOrWhiteSpace(str))
return false;
Char ch = str[0];
return Char.IsUpper(ch);
}
public static bool StartsWithLower(this String str) {
if (String.IsNullOrWhiteSpace(str))
return false;
Char ch = str[0];
return Char.IsLower(ch);
}
public static bool StartsWithNumber(this String str) {
if (String.IsNullOrWhiteSpace(str))
return false;
Char ch = str[0];
return Char.IsNumber(ch);
}
}
}
-
类库 UtilityLibrary.StringLib 包含一些方法,如 StartsWithUpper 、 StartsWithLower 和 StartsWithNumber ,这些方法将返回一个布尔值,该布尔值指示当前字符串实例分别以大写、小写和数字开头。
-
在.NET Core中,如果某个字符是大写,则 Char.IsUpper 方法返回true;如果某个字符是小写,则Char.IsLower方法返回true;同样,如果某个字符是数字字符,则Char.IsNumber方法返回true。
-
在菜单栏中,选择“生成”,然后选择“生成解决方案”。项目应该能够在没有错误的情况下编译。
-
我们的.NET Core控制台项目无法访问我们的类库。
-
现在,若要使用此类库,我们需要在控制台项目中添加此类库的引用。
为此,请展开FirstApp,然后右键单击“引用”,最后选择 Add Reference…
在“引用管理器”对话框中,选择我们的类库项目UtilityLibrary,然后单击 OK 。
现在让我们打开控制台项目的Program.cs文件,并将所有代码替换为以下代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UtilityLibrary;
namespace FirstApp {
public class Program {
public static void Main(string[] args) {
int rows = Console.WindowHeight;
Console.Clear();
do {
if (Console.CursorTop >= rows || Console.CursorTop == 0) {
Console.Clear();
Console.WriteLine("\nPress <Enter> only to exit; otherwise, enter a string and press <Enter>:\n");
}
string input = Console.ReadLine();
if (String.IsNullOrEmpty(input)) break;
Console.WriteLine("Input: {0} {1,30}: {2}\n", input, "Begins with uppercase? ",
input.StartsWithUpper() ? "Yes" : "No");
} while (true);
}
}
}
现在让我们运行应用程序,您将看到以下输出。
为了更好地理解,让我们在您的项目中使用您的类库的其他扩展方法。
.NET Core - Portable Class Library
在本章中,我们将讨论什么是PCL(可移植类库),以及为什么我们需要PCL。为了理解此概念,让我们打开上一章中创建的类库项目文件夹。
在该文件夹中,您会看到除了project.json和CS文件之外,我们还有一个*.xproj文件,原因在于Visual Studio将.NET Core项目类型设置为*.xproj,而不是*.csproj。
如Microsoft指出的那样,.xproj将逐渐消失,但它仍保留在预览2版本工具中。正如我们所介绍的,UWP应用程序使用.csproj。
现在实际上不可行的是引用*.xproj,而*.csproj也不会实现该功能,因为*.xproj将被淘汰。
所以,我们需要的是可以在控制台应用程序和UWP应用程序之间共享的类库,而PCL正是如此。
What is PCL
现在让我们了解PCL是什么−
-
通过 Portable Class Library 项目,您可以编写和生成在多个 .NET Framework 平台上运行的托管程序集。
-
您可以创建包含您希望在多个项目中共享(例如共享业务逻辑)的代码的类,然后从不同类型的项目引用这些类。
-
它还可以帮助您快速轻松地为 Microsoft 平台构建跨平台应用程序和库。
-
Portable 类库可以帮助您缩短开发和测试代码的时间和成本。
-
使用此项目类型编写和生成可移植的 .NET Framework 程序集,然后从面向多个平台(例如 Windows、Windows Phone 等)的应用程序引用这些程序集。
让我们现在从“解决方案资源管理器”中删除我们创建的类库。同时,从解决方案文件夹中将其删除,并进一步添加一个新项目项。
在左窗格中选择 Visual C# → Windows 模板,在中间窗格中选择“类库(可移植)”。
在名称字段中输入 StringLibrary,然后单击 OK 以创建此项目。
现在,我们需要选择要引用的目标框架。让我们暂时选择 Windows Universal 和 ASP.NET Core,然后我们将重新定位它。单击 OK 。
您会看到它已按 PCF 格式创建了一个新项目。让我们现在在“解决方案资源管理器”中右键单击 StringLibrary 项目并选择“属性”。
单击“目标 .NET 平台标准”。
单击”是“;现在与一个细微差别相同的类库。不同之处在于它也可以被 UWP 使用,因为它包含 *.csproj 文件,而不是 *.xproj。
现在,让我们添加一个新类;为此,您需要右键单击“解决方案资源管理器”中的项目并选择 Add → Class…
在中间窗格中选择“类”,在名称字段中输入 StringLib.cs ,然后单击 Add 。添加类后,替换 StringLib.cs 文件中的以下代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StringLibrary {
public static class StringLib {
public static bool StartsWithUpper(this String str) {
if (String.IsNullOrWhiteSpace(str))
return false;
Char ch = str[0];
return Char.IsUpper(ch);
}
public static bool StartsWithLower(this String str) {
if (String.IsNullOrWhiteSpace(str))
return false;
Char ch = str[0];
return Char.IsLower(ch);
}
public static bool StartsWithNumber(this String str) {
if (String.IsNullOrWhiteSpace(str))
return false;
Char ch = str[0];
return Char.IsNumber(ch);
}
}
}
让我们构建这个可移植类库项目,它应该在没有错误的情况下编译。现在,我们需要在我们的控制台项目中添加这个可移植类库的引用。因此,展开 FirstApp,右键单击“引用”,然后选择 Add Reference…
在“引用管理器”对话框中,选择我们可移植类库项目的 StringLibrary,然后单击 OK 。
您会看到 StringLibrary 引用已添加到控制台项目中,而且在 project.json 文件中也可以看到。
现在,您可以再次运行应用程序,您将看到相同的输出。
现在让我们在您的项目中使用可移植类库的其他扩展方法。同一个可移植库也将被您的 UWP 应用程序使用。
.NET Core - Adding References to Library
在本节中,我们将探讨如何向您的库添加引用。向库添加引用就像向其他项目(如控制台项目和 UWP 项目)添加引用一样。
您现在可以看到,PCL 项目默认会带有一些引用。您也可以根据需要为应用程序添加其他引用。
在 PCL 库中,您还可以看到 project.json 文件。
{
"supports": {},
"dependencies": {
"NETStandard.Library": "1.6.0",
"Microsoft.NETCore.Portable.Compatibility": "1.0.1"
},
"frameworks": {
"netstandard1.3": {}
}
}
向您的库添加引用的一个方法是直接在 project.json 文件中键入。正如您可以看到的,我们在依赖项部分中添加了一些引用,如下面的代码所示。
{
"supports": {},
"dependencies": {
"NETStandard.Library": "1.6.0",
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"System.Runtime.Serialization.Json": "4.0.3",
"Microsoft.EntityFrameworkCore": "1.1.0"
},
"frameworks": {
"netstandard1.3": {}
}
}
我们现在保存此文件,您会看到已将引用添加到您的库中。
向您的库添加引用的另一个方法是使用 NuGet 包管理器。现在,让我们右键单击 StringLibrary (Portable) 项目并选择 Mange NuGet Packages… 。
在“浏览”选项卡上,您可以搜索任何 NuGet 包;就我们而言,我们希望添加“System.Runtime.Serialization.Primitives”包。
单击 Install 按钮,它将显示以下屏幕。
现在,单击 OK 按钮。
最后,单击 I Accept 按钮以开始安装此 NuGet 包。安装完成后,您会看到“System.Runtime.Serialization.Primitives”NuGet 包已添加到您的库中。
.NET Core - Sharing Libraries
在本节中,我们将探讨如何将您的库作为 NuGet Package 共享,以便在其他项目中使用。创建包从希望打包并与其他人共享的代码开始,可以通过公用 nuget.org 图库或组织内的专用 图库进行共享。包还可以包括其他文件,例如在安装包时显示的 readme ,并且可以对某些项目文件进行转换。
现在,让我们考虑一个简单的示例,其中我们将从库中创建一个 NuGet 包。为此,请打开命令提示符并转到库项目的 project.json 文件所在的文件夹。
现在,让我们运行以下命令。
dotnet help
最后,您可以看到诸如 new、restore 和 build 之类的不同命令。
最后一个命令是 pack; 这将创建一个 NuGet 包。现在,让我们执行以下命令。
dotnet pack
您现在可以看到 NuGet 包已在 bin 文件夹中生成;让我们打开 bin\Debug 文件夹。
现在的问题是 NuGet 包中包含什么内容,要了解这一点,我们可以使用 NuGet 包资源管理器。现在,让我们打开 NuGet 包资源管理器。
选择第一个选项 Open a local package 。
选择 StringLibrary.1.0.0.nupkg 并单击 Open 。
你可以在“程序包内容”部分中看到我们只包含了 StringLibrary.dll。在“程序包元数据”部分中,你将看到有关此程序包的一些信息,例如 Id、版本和所有依赖项。
我们现在打开 StringLibrary.1.0.0.symbols.nupkg 。
在此 NuGet 程序包中,你会看到源文件以及 *.pdb 文件。如果你在 StringLib.cs 文件上双击,你还可以看到源代码。
这里的问题是,如何配置元数据(例如版本、作者和描述)等。
project.json 文件用于 .NET Core 项目,目的是定义项目元数据、编译信息和依赖项。我们现在打开 project.json 文件,并添加以下额外信息。
{
"authors": [ "Mark Junior" ],
"description": "String Library API",
"version" : "1.0.1-*",
"supports": {},
"dependencies": {
"Microsoft.EntityFrameworkCore": "1.1.0",
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"NETStandard.Library": "1.6.0",
"System.Runtime.Serialization.Json": "4.0.3",
"System.Runtime.Serialization.Primitives": "4.3.0"
},
"frameworks": {
"netstandard1.3": {}
}
}
你现在可以看到其他信息,如作者名称、描述和此处添加的版本。我们保存此文件,构建程序包项目,然后再次执行“dotnet pack”命令。
在 bin\Debug 文件夹中,你可以看到 StringLibrary NuGet 程序包已使用 1.0.1 版本生成;我们已在 NuGet Package Explorer 中将其打开。
你将看到更新的元数据。现在的问题是,我们如何在另一个程序包中使用它。
我们需要先在 NuGet 源中发布它,然后我们才能在另一个项目中使用它。
发布更新的元数据有两种选择:
-
Publish it to nuget.org
-
将元数据推送到私有 NuGet 源
此处我们将使用私有 NuGet 源,因为它比在 nuget.org 上设置帐户容易得多。要了解如何将包发布到 nuget.org,你可以按照此处 https://docs.microsoft.com/en-us/nuget/create-packages/publish-a-package 指定的所有准则进行操作。
按照以下步骤将更新的元数据推送到私有 NuGet 源。
Step 1 - 首先,我们需要 nuget 命令行实用工具,并且我们必须将其安装。我们现在打开 NuGet Package Manager,并搜索 nuget.commandline。
Step 2 - 选择 Nuget.Commandline,然后单击 Install 。
Step 3 - 单击 OK 以安装 Nuget.Commandline。你还可以通过从以下网址 https://dist.nuget.org/index.html 下载它并设置环境变量来手动安装它。
Step 4 - 安装完成后,我们重新打开命令提示符并转到 bin\Debug 文件夹(NuGet 程序包位于此文件夹中),并指定以下命令:
nuget add StringLibrary.1.0.1.nupkg -Source D:\PrivateNugetPackages
Step 5 - 在以上命令中,我们将 StringLibrary.1.0.1.nupkg 程序包添加到我们的私有源,位置为 D:\PrivateNugetPackages , -Source 指定包源。
Step 6 - 你可以看到已安装 StringLibrary ;可以将 StringLibrary 进一步添加到私有源。
Step 7 − 让我们转到该文件夹。
Step 8 − 在 stringlibrary 文件夹的内部,你会看到另一个具有版本名称的文件夹,此处为 1.0.1。
NuGet 包位于此处。
Creating a Xamarin.Forms Project
在本章中,我们将讨论如何使用已创建并发布到私有 NuGet 源的 NuGet 包。因此,我们首先将创建一个 Xamarin.Forms 项目。我们需要先了解什么是 Xamarin.Forms。
-
Xamarin.Forms 是一个允许开发人员快速创建跨平台用户界面的框架。
-
Xamarin.Forms 是一个跨平台本地支持 UI 工具包抽象层,它允许开发人员轻松地创建用户界面,该界面可以跨 Android、iOS、Windows 和 Windows Phone 共享。
-
用户界面使用目标平台的本机控件进行渲染,从而允许 Xamarin.Forms 应用在每个平台保留着合适的外观和感觉。
要启动 Xamarin.Forms,我们需要在 Visual Studio 2015 中一些附加功能。我们修改一下你的 Visual Studio 2015,并确保已选择了以下跨平台移动开发选项。
完成安装后,我们通过选择 Tools → Options… 来更新 Xamarin
向下滚动并展开左侧窗格中的 Xamarin,然后选择 Other 。在对话框的右上角,单击 Check Now 以查看是否有可用的更新。
你可以看到有可用的更新,我们单击 Download 按钮开始下载。下载完成后,你会收到安装更新的通知。
我们现在再次打开 Visual Studio,并选择 File → New → Project… 菜单选项。
在左侧窗格中,选择 Visual C# → Cross-Platform 模板,在中间窗格中,选择 Blank Xaml App (Xamarin.Forms Portable) 。在“名称”字段中输入名称,然后单击“确定”。
选择目标版本和最低版本并单击“确定”。
你会看到一系列项目;在顶部我们有 PCL 库,该库将在所有平台(如 Android、iOS、UWP、Windows 8.1 和 Windows Phone 8.1)间共享。
在此,我们将聚焦于 PCL 库,并将一些代码引入此处。让我们展开代码。
在该 Xamarin.Forms 模板中,你可以看到通用 App.xaml 和 MainPage.xaml,它们使用了能在这些平台间工作的 Xamarin.Forms XAML 框架。
我们需要导入我们的代码,而且我们还需要我们在上一章中设置的私有 NuGet 提供程序。
我们现在打开 NuGet 包管理器。单击包源下拉列表旁边的齿轮。
我们需要在此处添加我们的专用馈送,点按 plus (+) button 。
您将看到在 Available package sources 部分中添加了另一个复选框,让我们指定一个名称和源路径,然后点按 OK 。
让我们转到“浏览”选项卡,然后从“程序包源”下拉列表中选择“PrivateSource”,您将看到 StringLibrary NuGet 程序包。选择 StringLibrary,然后点按 Install 。
点按“确定”,您将看到一个错误。
我们无法使用 .NETPortable 配置文件版本 259 的库,我们将在下一章中修复此错误。
.NET Core - PCL Troubleshooting
在本章中,我们将修复在 Xamarin.Forms 项目中从我们的专用馈送安装 NuGet 程序包时遇到的错误。
我们将进一步简要了解问题。首先,让我们右键单击 PCL 库并选择“属性”。
在此页面上,您将看到所有目标框架系列。从错误中,您会看到 .NETPortable 配置文件 259 与我们的 StringLibrary 1.0.1 不兼容。但是,它试图从 .NET Standard 1.1 库获取引用。
现在让我们查看 .NET Standard 库并确定哪个平台与我们的库不兼容。
您可以看到 Windows Phone Silverlight 8 与 .NET Standard 1.0 兼容。如果您打开以下网页,您将看到 Profile259 只能支持 .NET Standard 1.0。
现在让我们取消选中 Windows Phone Silverlight 8。
单击 OK 按钮。
现在,要修复此问题,请点按“确定”,取消“更改目标”对话框,然后打开程序包管理器控制台,并执行以下命令。
PM > Uninstall-Package Xamarin.Forms
现在让我们转到 PCL 库的“属性”。点按“更改”按钮。
取消选中 Windows Phone Silverlight 8,然后点按“确定”。
您现在可以看到,Windows Phone Silverlight 8 不再出现在“目标框架”中了。您还可以看到当前目标的配置文件。要看到此内容,让我们卸载 PCL 库并编辑 XamarinApp.csproj 文件。
您现在可以看到,TargetFrameworkProfile 现在是 Profile111。
如果您打开文档,您将看到 Profile111 支持 .NET Standard 1.1。
现在,让我们重新加载 PCL 并打开 NuGet 程序包管理器,然后尝试从专用馈送安装 StringLibrary 程序包。
从“依赖关系行为”下拉列表中,选择“忽略依赖关系”,然后点按 Install 。
您可看到 StringLibrary 包已从专用源进行安装。如果您展开 PCL 的引用,您将看到 StringLibrary 引用也按以下所示添加进来。
我们已针对 Windows Phone Silverlight 8 问题卸载了 Xamarin.Forms。需要重新安装 Xamarin.Forms。建议安装相同版本。
一旦完成安装,让我们在您的应用程序中使用 StringLibrary 功能。
.NET Core - Create a Testing Project
在本章中,我们将讨论如何使用 .NET Core 创建测试项目。单元测试是一个软件开发过程,其中包括应用程序中最小的可测试部分,即单元。它们会被单独独立地进行检查,以了解操作是否正确。单元测试可以自动化,也可以手动进行。
现在打开“新建项目”对话框并选择 Visual C# → .NET Core 模板。
在此对话框中,您可以看到没有用于单元测试的项目模板。为了创建单元测试项目,我们应该使用命令行实用工具。我们进入刚才创建的解决方案文件夹;创建一个测试文件夹并在测试文件夹内创建一个新文件夹并将其命名为 StringLibraryTests 。
现在,让我们使用 dotnet 命令行实用工具执行以下命令来新建一个测试项目:
dotnet new -t xunittest
您现在可以看见创建了一个新的 C# 项目;让我们执行 v 命令查看此文件夹,您将看到 project.json 和 Tests.cs 文件,如下图所示。
以下是 project.json 文件中的代码。
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable"
},
"dependencies": {
"System.Runtime.Serialization.Primitives": "4.1.1",
"xunit": "2.1.0",
"dotnet-test-xunit": "1.0.0-rc2-192208-24"
},
"testRunner": "xunit",
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"imports": [
"dotnet5.4",
"portable-net451+win8"
]
}
}
}
以下是 Test.cs 文件中的代码。
using System;
using Xunit;
namespace Tests {
public class Tests {
[Fact]
public void Test1() {
Assert.True(true);
}
}
}
要从 NuGet 获取必需的依赖项,让我们执行以下命令:
dotnet restore
当还原必需的依赖项后,我们就可以运行该测试。
您可看到编译成功;向下看可以看到有关执行的测试的一些信息。
当前,我们执行了 1 个测试,0 个错误,0 个失败,0 个跳过,执行过程耗费的时间也列为信息。
.NET Core - Running Tests in Visual Studio
在本章中,我们将讨论如何在 Visual Studio 中运行测试。.NET Core 的设计考虑了可测试性,因此为应用程序创建单元测试比以往任何时候都更容易。在本章中,我们将在 Visual Studio 中运行和执行我们的测试项目。
让我们在 Visual Studio 中打开 FirstApp 解决方案。
您会看到它只有两个项目,并且您将看不到测试项目,因为我们尚未在解决方案中添加该项目。
让我们先添加一个文件夹,并称其为 test 。
右键单击 test 文件夹。
选择 project.json 文件,然后单击 Open 。
以下屏幕截图显示 Tests.cs 文件中的代码作为输出。
这是默认实现,它仅仅测试 True 是否等于 true。它基于 xUnit 测试框架,你会看到一个注解和表示测试方法的 Fact 特性。
using System;
using Xunit;
namespace Tests {
public class Tests {
[Fact]
public void Test1() {
Assert.True(true);
}
}
}
以下是 project.json 文件的实现。
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable"
},
"dependencies": {
"System.Runtime.Serialization.Primitives": "4.1.1",
"xunit": "2.1.0",
"dotnet-test-xunit": "1.0.0-rc2-192208-24"
},
"testRunner": "xunit",
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"imports": [
"dotnet5.4",
"portable-net451+win8"
]
}
}
}
在 project.json 文件中,对测试框架最重要的依赖项是 xunit,该依赖项引入了 Fact 特性。它引入了 xunit 的测试框架和用于测试的 API。
我们还有 dotnet-test-xunit ,这是一款适配器,以便 xunit 能够与 .NET Core 协同工作,特别是与 dotnet test 命令行实用工具协同工作。接下来,你会看到将运行 xunit 的 testRunner 以及 netcoreapp1.0 框架。
你将在下面看到 .NETCore.App 依赖项。
若要在 Visual Studio 中运行测试,让我们从 Test → Window → Test Explorer 菜单选项中打开测试浏览器。
你可以看到,Visual Studio 会自动检测测试。测试名称包含 namespace.className.TestMethodName 。现在,让我们单击 Run All button in Test Explorer 。
它会首先构建代码,然后运行测试,并且你会看到测试花费的总时间。让我们更改测试方法,以便测试失败时我们能看到输出。
using System;
using Xunit;
namespace Tests {
public class Tests {
[Fact]
public void Test1() {
Assert.True(false);
}
}
}
让我们通过单击 Run All 按钮链接再次执行测试。
你现在可以看到 test 故障。
.NET Core - Testing Library
在本章中,我们将测试 StringLibrary,为此,我们需要重新排列我们的项目,以便按照默认惯例进行。
打开 global.json 文件。
{
"projects": [ "src", "test" ],
"sdk": {
"version": "1.0.0-preview2-003131"
}
}
你将在该文件的顶部看到项目设置,它默认设置了一些文件夹,例如 src 和 test 。
按照惯例,我们必须在这些文件夹中保存项目,这是新惯例,将用作 .NET Core 的一部分。
在解决方案资源管理器中,你可以看到控制台项目和库项目都在 src 文件夹中,而测试项目在 test 文件夹中。
解决方案资源管理器中的项目结构不代表项目在磁盘上的实际位置。打开解决方案文件夹,你会看到 StringLibrary 项目不在 src 文件夹中。
你可以看到 src 和 test 文件夹都映射到 global.json 文件中指定的惯例。但是,我们有一个 StringLibrary 项目不符合惯例。现在将 StringLibrary 项目添加到 src 文件夹中。
在 src 文件夹中,我们有两个项目,我们需要修复问题,以便我们可以正确使用所有项目。回到 Visual Studio,右键单击 StringLibrary 项目,并选择“删除”选项。它不会删除它,只会删除项目。
现在,右键单击 src 文件夹,并选择 Add → Existing Project…
浏览到 StringLibrary 项目,该项目现位于 src 文件夹内,选择 StringLibrary.csproj 文件并单击 Open 。
现在我们必须移除 StringLibrary 的引用,该引用来自控制台应用程序的 project.json 文件。
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
},
"NuGet.CommandLine": "3.5.0",
"System.Runtime.Serialization.Json": "4.0.3"
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": { },
"imports": "dnxcore50"
}
}
}
保存更改,然后再次在控制台项目中添加 StringLibrary 的引用。
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
},
"NuGet.CommandLine": "3.5.0",
"System.Runtime.Serialization.Json": "4.0.3"
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"StringLibrary": {
"target": "project"
}
},
"imports": "dnxcore50"
}
}
}
现在一切应该恢复正常,你可以构建 StringLibrary ,然后构建 FirstApp (控制台项目),而不会出现任何错误。现在让我们使用 xunit 来测试 StringLibrary 功能。我们需要将 StringLibrary 引用添加到我们的测试项目中。右键单击 StringLibraryTests 项目的引用,然后选择添加引用…
单击 OK ,这会向我们的测试项目添加 StringLibrary 的引用。现在让我们替换 Tests.cs 文件中的以下代码。
using System;
using Xunit;
using StringLibrary;
namespace Tests {
public class Tests {
[Fact]
public void StartsWithUpperCaseTest() {
string input = "Mark";
Assert.True(input.StartsWithUpper());
}
[Fact]
public void StartsWithLowerCaseTest() {
string input = "mark";
Assert.True(input.StartsWithLower());
}
[Fact]
public void StartsWithNumberCaseTest() {
string input = "123";
Assert.True(input.StartsWithNumber());
}
}
}
你可以看到我们有三个测试方法,它们会测试 StringLibrary 的功能。让我们单击 Run All 链接,你将在测试资源管理器中看到以下输出。
你还可以从命令行运行测试。让我们打开命令提示符并执行 dotnet test 命令。
Managed Extensibility Framework
在本章中,我们将讨论可托管扩展框架 (MEF)。MEF 可用于第三方插件扩展,或者它可以为常规应用程序带来松散耦合的插件式架构的优势。
-
MEF 是一个用于创建轻量级、可扩展应用程序的库。
-
它允许应用程序开发人员发现和使用扩展,而无需进行任何配置。
-
MEF 是 .NET Framework 4 的组成部分,并且在所有使用 .NET Framework 的地方都可以使用,这提高了大型应用程序的灵活性、可维护性和可测试性。
-
无论你的客户端应用程序使用的是 Windows 窗体、WPF 还是任何其他技术,还是使用 ASP.NET 的服务器应用程序,你都可以使用 MEF。
-
MEF 已移植为 Microsoft.Composition ,并且也部分移植到了 .NET Core。
-
仅移植了 System.Composition ,而 System.ComponentModel.Composition 尚未可用。这意味着,我们没有可以在目录中从程序集中加载类型的目录。
在本章中,我们将仅了解如何在 .NET Core 应用程序中使用 MEF。
让我们了解一个简单的示例,其中我们将在 .NET Core 控制台应用程序中使用 MEF。现在,让我们创建一个新的 .NET Core 控制台项目。
在左窗格中,选择 Templates → Visual C# → .NET Core,然后在中间窗格中,选择控制台应用程序 (.NET Core)。
在名称字段中输入项目的名称,然后单击确定。
创建项目后,我们需要添加对 Microsoft.Composition 的引用,以便我们能够使用 MEF。为此,让我们在解决方案资源管理器中右键单击该项目并 Manage NuGet Packages…
搜索 Microsoft.Composition ,然后单击 Install 。
单击 OK 按钮。
单击 I Accept 按钮。
当安装完成后,您将在“引用”中发现一个错误。
让我们打开 project.json 文件。
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.Composition": "1.0.30",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {
"imports": "dnxcore50"
}
}
}
您会看到已添加了 Microsoft.Composition 依赖项,但问题是此程序包与 dnxcore50 不兼容。因此,我们需要导入 portablenet45+win8+wp8+wpa81 。现在,让我们用以下代码替换 project.json 文件。
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.Composition": "1.0.30",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {
"imports": "portable-net45+win8+wp8+wpa81"
}
}
}
保存此文件,您将看到该错误已纠正。
如果您展开“引用”,就会看到 Microsoft.Composition 的一个引用。
首先,我们需要创建一个要导出的接口,然后实现该接口并将该类装饰为导出属性。现在,让我们添加一个新类。
在“名称”字段中输入您类的名称,然后单击 Add 。
让我们在 PrintData.cs 文件中添加以下代码。
using System;
using System.Collections.Generic;
using System.Composition;
using System.Linq;
using System.Threading.Tasks;
namespace MEFDemo {
public interface IPrintData {
void Send(string message);
}
[Export(typeof(IPrintData))]
public class PrintData : IPrintData {
public void Send(string message) {
Console.WriteLine(message);
}
}
}
如上所述,在 Microsoft.Composition 命名空间中不提供目录。因此,它会加载装配中具有导出属性的所有类型,并将它们附加到导入属性中,如 Program.cs 文件中的 Compose 方法中所示。
using System;
using System.Collections.Generic;
using System.Composition;
using System.Composition.Hosting;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace MEFDemo {
public class Program {
public static void Main(string[] args) {
Program p = new Program();
p.Run();
}
public void Run() {
Compose();
PrintData.Send("Hello,this is MEF demo");
}
[Import]
public IPrintData PrintData { get; set; }
private void Compose() {
var assemblies = new[] { typeof(Program).GetTypeInfo().Assembly };
var configuration = new ContainerConfiguration()
.WithAssembly(typeof(Program).GetTypeInfo().Assembly);
using (var container = configuration.CreateContainer()) {
PrintData = container.GetExport<IPrintData>();
}
}
}
}
现在,让我们运行您的应用程序,您将看到它正在通过实例化 PrintData 类来运行。
要详细了解 MEF,让我们访问以下网址 https://msdn.microsoft.com/en-us/library/dd460648%28v=vs.110%29.aspx ,了解更多详情。
.NET Core - SDK
在本章中,我们将了解 .NET Core 中的即将推出的功能。我们将通过在浏览器中打开以下网址来开始使用 .NET 命令行工具 https://github.com/dotnet/cli
如需了解有关进度的更多信息,您可以向下滚动并下载最新版本的 .NET Core SDK,您将看到安装器和二进制文件部分。
您可以看到针对不同操作系统的最新预览工具版本,让我们根据您的操作系统选择安装器。
我们正在研究 .NET Core 2.0 的预览 1。
现在,让我们查看我们的当前工具,为此打开命令提示符并执行以下命令。
dotnet --info
您将在您的系统中看到有关当前安装的 .NET 命令行工具版本的如下信息。
您能看到当前我们有 preview2 工具。我们现在运行以下命令,以查看 new 命令。
dotnet help new
对于项目的新的命令语言,您可以选择如 C# 和 F# 以及项目的类型等。
我们现在来看一下 .NET Core 最新版本的更改。一旦下载了安装程序,双击以安装它。单击“安装”。
以下屏幕截图显示了安装过程。
它将会开始安装过程。一旦安装完成,关闭此对话。
打开命令提示符并执行以下命令。
dotnet --info
您将会看到如下所示您的系统中当前安装的 .NET 命令行工具的版本信息。
您现在能看到我们有 .NET Core 2 的 preview1 工具。我们现在在命令提示符中运行以下代码,以了解 .NET Core 2 preview1 中的新命令。
dotnet help new
该命令会帮助您将包以及包缓存下载到中。
该命令打开以下网页,其中包含 .NET Core 2 preview1 中有关新命令的信息。
我们向下滚动,您现在可以看到我们可以使用更多的模板创建 .NET Core 应用程序。
我们现在可以使用命令行来创建 mstest, web, mvc 和 webapi 项目。
.NET Core - MSBuild and project.json
我们现在来讨论这一变更带来的优势 −
-
它将使现有 Visual Studio 解决方案过渡到 .NET Core 变为直接的。
-
这是一个巨大的变更,它还将支持利用基于 MSBuild 的现有的 CI/RM 投资。
-
在 MSBuild 中构建期间,我们可以考虑增量编译、求解构建时间依赖项、配置管理等。
-
准时交付 dotnet cli 需要很多工作,因为它不仅是关于 ASP.NET Core,还包括控制台应用程序、UWP 应用程序等。
以下是 MSBuild 和 *.csproj 中的更改 −
-
Project.json 文件 ( .xproj) will be replaced by MSBuild ( .csproj)。
-
project.json 中的功能将开始重新合并回到 *.csproj 中。
-
尚不清楚他们将如何处理程序包列表,但有人提到他们可能会将其作为 json 文件保存在 nuget.json 中,或将其合并到 *.csproj 中。
-
如果使用 Visual Studio,那么此过渡理论上应该是平滑且潜在自动化的。
Advantages of MSBuild
-
MSBuild 是开源的,可在 GitHub 中获取,并且势必将完全跨平台。
-
MSBuild 将显著简化并精简 *.csproj 的结构。
-
Microsoft 还在推出一个新项目系统,该系统将使大量场景无需 Visual Studio 即可使用,且详细信息已在此 Url https://github.com/dotnet/roslyn-project-system/ 中给出。
-
目标是即使使用 MSBuild 设置,在 Visual Studio IDE 中和在其外部处理构建和项目也应同样无缝。
MSBuild vs project.json
现在通过执行以下命令使用 .NET Core preview2 工具包创建新的控制台项目。
dotnet new -t console
要查看在此项目中创建的所有文件,请运行 dir 命令。
你可以看到创建了两个文件,即 Program.cs 和 project.json 文件。
现在通过执行以下命令使用 .NET Core 2 preview1 工具包创建一个控制台应用程序。
dotnet new console
要查看在此项目中创建的所有文件,请运行 dir 命令。你可以看到创建了三个文件,即 Program.cs, NuGet.config 和 MSBuild.csproj ,而不是 project.json 文件。
现在让我们并排比较 project.json 和 MSBuild.csproj 文件。
在左边,我们以 json 格式的文件,而在右边,文件是 XML 格式。你可以在 project.json 文件,在依赖关系部分,里面的 netcoreapp1.0 ,而在 MSBuild.csproj 文件,你将看到 netcoreapp2.0 。
Restoring and Building with MSBuild
在本章,我们将讨论如何使用命令行实用程序来还原和构建你的 MSBuild (*.csproj) 文件。要查看 .NET Core 2.0 预览版 1 中的命令,让我们运行以下命令。
dotnet help
你将看到所有像 new、restore、build 等命令。
以下是 Program.cs 文件中的默认实现。
using System;
namespace MSBuild {
class Program {
static void Main(string[] args) {
Console.WriteLine("Hello World!");
}
}
}
现在让我们执行以下命令以查看进度。
dotnet build
你将会看到许多错误。这些错误需要更正。
现在,让我们运行以下命令。
dotnet restore
你可以看到所有软件包已还原。还生成了一些新文件夹和文件。
要查看目录结构,让我们运行以下命令。
tree /f
以下是目录结构 -
现在让我们再次运行以下命令重新生成项目。
dotnet build
现在你的项目将成功构建,不会有任何错误,也会创建 MSBuild.dll。
要查看输出,让我们运行以下命令 -
dotnet run
你可以在控制台上看到以下输出。
.NET Core - Migrations
在本章中,我们将迁移包含 ` project.json ` 文件构建系统而不是 ` MSBuild ( .csproj` 的控制台应用程序。因此,我们有一个旧项目,其中包含以下文件。
现在的问题是,我们为什么需要迁移?此项目是使用 .NET Core 1.0 Preview 2 工具创建的,现在我们已经安装了 .NET Core 2.0 Preview 1 工具。现在,当你使用 .NET Core 2.0 命令行实用工具构建此应用程序时,你将看到以下错误。
这是因为 ` project.json ` 构建系统在 .NET Core 2.0 中不再可用,所以我们需要迁移才能正常工作。要查看可用命令,让我们运行以下命令。
dotnet help
在命令部分,你可以看到不同的命令,你还可以看到 ` migrate ` 命令,它将基于 project.json 的项目迁移到基于 MSBuild 的项目。
现在,让我们运行以下命令。
dotnet migrate
你将看到迁移过程的摘要,在这里你还可以看到项目已成功迁移。
现在让我们使用以下命令查看目录结构。
tree /f
你现在将在项目根目录中看到 *.csproj
文件以及 Program.cs
文件,而 project.json
已移动到备份文件夹。
让我们打开 ` console.csproj ` 文件。现在,你可以通过运行以下命令使用 MSBuild 系统还原并构建此项目。
dotnet restore
你现在可以看到所有软件包已还原。
你现在可以使用以下命令构建你的项目。
dotnet build
现在你可以看到项目已使用 MSBuild 成功构建,且 ..\bin\Debug\netcoreapp1.0 文件夹中也生成了 console.dll。
以下屏幕截图显示了目录结构和文件。