.net应用程序和工具

1.1  从.NET Framework 到.NET Core,再到.NET

 .net的第一个版本发布于2002年。从那之后,.net发生了很多变化。.net的第一个时代是.net  framework的时代,它为Windows桌面开发提供了Windows Forms,为创建Web应用程序提供了Web Forms。.net的这个版本只能用于Microsoft Windows。当时,Microsoft还在ECMA为C#创建了一个标准。

         后来,Silverlight 使用了这种技术的一个子集,通过一个浏览器插件在浏览器中运行其功能有限的运行库。在这个时候,一家名为Ximian的公司开发了Mono运行库,该公司提供了Microsoft 的.NET功能的一个子集,可用于Linux 和 Android。再后来,Novell收购了Ximian,而Novcll后来又被The Attachmate Group 收购。由于新公司对NET 失去了兴趣,Ximian的创始人Miguel de Icaza创办了Xamarin 公司,并将值得关注的.NET 部分带到了他的新公司,开始创建 Android和 ioS可用的.NET项目。如今,Xamarin 隶属于 Microsoft,Mono 运行库则成为 dotnet 运行库存储库(https://github.com/dotnet/runtime)的一部分。

       Silverlight 为不同外形尺寸的其他设备开启了NET开发时代,这些设备对于.NET有不同的需求.长期来看,Silverlight 没有获得成功,因为之后出现的HTML5提供了原来只能通过使用浏览器插件获得的功能。但是,Silverlight 开始让.NET 走向不同的方向,最终导致.NETCore问世。

       .NET Core 是NET 问世之后最大的变化。.NET 代码变得开源,允许为其他平台创建应用,并且.NET的新代码库使用了现代设计模式。下一步的进展合情合理:NETCore3.1之后的版本被命名为.NET5,去掉了Core这个词,并且跳过了版本4。这是为了告诉.NETFramework的开发人员,.NET Framework4.8之上还有更高的版本,现在是时候转到NET5来创建新的应用程序了。

       对于使用.NET Core 的开发人员,这种转变很容易,只需要改变现有应用程序的目标框架版本号即可。从.NET Framework迁移应用程序则没有那么简单,取决于应用程序的类型,可能需要或多或少的修改。.NET Core 3.x 支持 WPF和Windows Forms应用程序。对于这些应用程序类型,转变到 .NET可能并不难。但是,现有的.NET Framework WPF 应用程序可能有一些功能不能轻松地转移到新的 .NET 上。例如,.NET Core 和.NET 5不支持应用程序域。将 Windows Communications Foundation(WCF)服务移动到.NET 5就更加困难了。新的.NET时代不支持WCF的服务器部分。因此,需要使用满足需求的ASPNETCore WebAPI、gRPC或另外一种通信技术来重写应用程序的WCF服务。

        对于现有应用程序,继续使用.NET Framework而不是转向新的.NET可能更加有用,因为这个旧框架在未来的很多年中仍然会被继续维护。Windows 10中默认安装了.NET Framework,而且.NET Framework 的目标支持时间与Windows10版本的支持时间一样长。

       新的 .NET和NuGet 包允许 Microsot提供更快的更新周期来交付新特性。在创建应用程序时,决定使用什么技术并不容易。本章将帮助你进行决策。本章将介绍可用于创建Windows和Web应用程序及服务的不同技术,如何选择数据库访问技术,以及如何从旧技术迁移到新技术。

1.2  .net术语

在深入介绍之前,你应该理解概念和一些重要的.NET术语,例如.NETSDK包含什么,以及.NET运行库是什么。还应该清晰地理解.NETFramework 和.NET,何时使用.NET Standard,以及NuGet包和NET名称空间。
1.2.1 NET SDK
要开发.NET应用程序,需要安装.NETSDK。SDK中包含.NET命令行接口(command-line interface,CLI )、工具、库和运行库。使用.NET CLI可以基于模板创建新应用程序,恢复包,生成和测试应用程序,以及创建开发包。本章稍后的“.NET CLI”一节将介绍如何创建和生成应用程序。
如果你使用的是 Visual Studio 2019,则安装Visual Studio 的时候会自动安装 .NET SDK。如果你没有安装Visual Studio,则可以从 https://dot.net 安装SDK。该网址说明了如何在Windows、macOS和Linux 系统上安装.NETSDK。
我们可以安装.NET SDK的多个版本。下面的命令显示了系统上安装的所有不同版本的SDK。默认情况下,将使用最新版本。
> dotnet --list-sdks
注意:
要运行命令,需要打开命令提示。有多种不同的方式可以打开命令提示:使用Windows 内置的命令提示;安装新的Windows终端;如果安装了Visual Studio,可以启动开发者命令提示;或者可以使用bash shell。本章的“开发工具”小节将详细介绍Windows终端。
如果不想使用最新版本的SDK,可以创建一个global . json文件。下面的命令:
> dotnet new globaljson
将在当前目录中创建global.json文件。该文件包含version元素,其值为当前使用的版本号。你可以将这个版本号改为已安装的其他SDK版本:
"sdk":(
"version": "5.0.202"
  }
}
在global.json的目录及其子目录中,将使用指定的SDK版本。使用下面的命令可以验证这一点:
> dotnet --version
         1.2.2  .NET运行库
在目标系统中,不需要安装.NET SDK,只需要安装.NET运行库。运行库包含全部核心库和dotnet驱动程序。
dotnet 驱动程序用于运行应用程序,例如,使用下面的命令可以运行Hello World应用程序:
> dotnet hello-world.dll
在 htps://dot.net上,不只可以找到关于如何在不同平台上下载和安装 SDK的说明,还可以找到关于如何下载和安装运行库的声明。
除了在目标系统上安装运行库,还可以将运行库作为应用程序的一部分交付(这被称为自包含部署)。这种技术与,NETFramework 应用程序有很大区别,本章的“使用.NET CLI”小节将进行介绍。
要查看系统上安装了哪些运行库,可以使用下面的命令:
dotnet --list-runtimes
        1.2.3  公共语言运行库
C#编译器将C#代码编译为Microsoft Intermediate Language (IL)代码。这种代码有些类似于汇编代码,但具有更加面向对象的特性,IL 代码由公共语言运行库(Common Language Runtime,CLR)运行。那么,CLR是怎样做的呢?
       CLR把 IL代码编译为原生代码。.NET程序集中的代码由一个即时(Just-In-Time,JIT)编译器编译。该编译器创建平台特定的代码。运行库中包含一个名为RyuJIT的JIT编译器,它比之前的编译器更快,而且对于在使用Visual Studio调试应用程序的过程中使用“编辑并继续”功能提供了更好的支持。
       运行库还包括一个带有类型加载器的类型系统,类型加载器负责从程序集中加载类型。类型系统中的安全基础设施验证是否允许使用某些类型系统结构,如继承。
       创建类型的实例后,实例还需要销毁,内存也需要回收。运行库的另一个特性是垃圾收集器。垃圾收集器从托管堆中清除不再引用的对象的内存。
运行库还负责线程的处理。在C#中创建托管的线程时,线程不一定来自底层操作系统。运行库负责线程的虚拟化和管理。
1.2.4  .NET编译平台
  随着SDK安装的C#编译器属于.NET编译平台,这个编译平台名为Roslyn。Roslyn允许你与编译过程交互,处理语法树,以及访问语言规则定义的语义模型。你可以使用Roslyn来编写代码分析器和重构功能。还可以将Roslyn与C# 9的一个新特性代码生成器结合使用。
1.2.5  .NET Framework
.NET Framework是旧.NET的名称,其最新版本是.NET Framework 4.8。使用这个框架创建新的应用程序没有太大帮助,不过,你仍可以维护使用.NET Framework 4.8编写的现有应用程序,因为这项技术在未来的很多年间仍会被支持。如果现有应用程序并不能从使用新技术获益,并且维护工作量不大,那么短期内没有必要转为使用新技术。
      取决于现有应用程序使用的技术,转为使用.NET可能并不困难。从.NET Core3开始,新技术被用于支持WPF和Windows Forms。但是,WPF和Windows应用程序使用的一些特性可能要求修改应用程序架构。
      .NET的新版本不再支持一些技术,包括ASP.NET Web Forms、Windows Communication Foundation(WCF)和Windows Workflow Foundation(WF)。在不能使用ASP.NET Web Forms的情况下,你可以使用ASP.NET Blazor重写应用程序。在不能使用WCF的情况下,你可以使用ASP.NET Core Web API或gRPC。在不能使用WF的情况下,转为使用Azure Logic Apps可能会有帮助。
1.2.6  .NET Core
.NET Core是新的.NET,所有新技术都使用它。这个框架是开源的,可以在http://www.github.com/dotnet上找到它。其运行库是CoreCLR库;其框架存储在CoreFX存储库中,包含集合类、文件系统访问、控制台和XML等。
       .NET Framework要求必须在系统上安装应用程序需要的特定版本,而在.NET Core 1.0中,框架(包括运行库)是与应用程序一起交付的。以前,把ASP.NET Web应用程序部署到共享服务器上有时可能有问题,因为提供商安装了旧版本的.NET。这种情况已经一去不复返了。现在可以将运行库与应用程序一起交付,并不依赖于服务器上安装的版本。
     .NET Core以模块化的方式设计。该框架分成数量很多的NuGet包。为了让你不必处理所有的包,.NET Core支持使用元包引用一起工作的小包。这种特性在.NET Core 2.0和ASP.NET Core 2.0得到进一步的改进。在ASP.NET Core 2.0中,只需要引用Microsoft.AspNetCore.All,就可以得到ASP.NET Core Web应用程序通常需要的所有包。
.NET Core可以很快更新。即使更新运行库,也不影响现有的应用程序,因为运行库与应用程序一起安装。现在,Microsoft可以更快速的发布改进后的.NET Core,包括运行库。
1.2.7  .NET
  从.NET 5 开始,.NET Core有了一个新名称:.NET。从名称中删除了“Core”这个词,应该会让仍在使用.NET Framework的开发人员明白,从今以后不会再有.NET Framework的新版本,也不会再为.NET Framework开发新的特性。如果要创建新的应用程序,应该使用.NET。
1.2.8  .NET Standard
      在创建和使用库时,.NET Standard是一个重要的规范。.NET Standard不是一个实现,而是一个协定。本协定规定了需要实现哪些API。在每个新的.NET Standard版本中都添加了新的API。但API从不会被删除。例如,.NET Standard2.1 中的API 比.NET 1.6更多。
     创建库的时候,你可能想使用尽可能多的API,所以建议选择最新的.NET Standard。但是,.NET Standard的版本越高,意味着支持该标准的平台数量越少,所以这也是一个考虑因素。
     可以在https://docs.microsoft.com/dotnet/standard/net-standard中找到.NET Standard的平台支持表。例如,.NET Framework 4.6.1和更高版本最高支持.NET Standard 2.0。.NET Core 3.0和更高版本(包括.NET 5及更高版本)支持.NET Standard 2.1。通用Windows平台(Universal  Windows Platform)版本10.0.16299支持.NET Standard 2.0。Xamarin.Android 10.0支持.NET Standard 2.1。
     从.NET 5开始,.NET Standard变得不再重要。如果你使用.NET 5创建库,可以在.NET 5、.NET 6及更高版本的应用程序中使用这些库。与此类似,如果你使用.NET 7创建库,则可以在使用.NET 7或更高版本编写的应用程序中使用这些库。
    但是,我们不能预测.NET Framework、Mono和其它较老的技术是否会慢慢消亡,所以在未来的许多年间,如果你的库需要支持较老的技术,则仍然需要.NET Standard。
1.2.9  NuGet包
        在早期,程序集是应用程序的可重用单元。添加对程序集的一个引用,以便在自己的代码中使用公共类型和方法的时候,仍可以这样使用程序集(一些程序集必须这样使用)。然而,使用库可能不仅意味着添加一个引用并使用它。使用库也意味着一些配置更改,或者可以通过脚本来利用一些特性。目标框架决定了你能够使用什么二进制文件。这是在NuGet包中打包程序集的一个原因。NuGet包是一个zip文件,其中包含程序集(或多个程序集)、配置信息和PowerShell脚本。
       使用NuGet包的另一个原因是,它们很容易找到,它们不仅可以从微软公司找到,也可以从第三方找到。NuGet包很容易在NuGet服务器http://www.nuget.org上获得。
       可以使用.NET CLI在应用程序中添加NuGet包 :
       >dotnet  add  package  <package-name>
       在Visual  Studio项目的引用中,可以打开NuGet包管理器(NuGet Package Manager),在该管理器中可以搜索包,并将其添加到应用程序中。这个工具允许搜索还没有发布的包(包括预发布选项),定义应该在哪个NuGet服务器中搜索包。搜索包的一个地方是自己的共享目录,其中放置了内部使用的包。
1.2.10  名称空间
      .NET提供的类组织在名称空间中,它们大多以System或Microsoft开头。下表描述了一些名称空间,帮助你理解名称空间的层次结构。
名称空间
说明
System.Collections
这是集合的根名称空间。其子名称空间也包含集合,如System.Collections.Concurrent和System.Collections.Generic
System.Diagnostics
这是诊断信息的根名称空间,如事件记录和跟踪(在System.Diagnostics.Tracing名称空间中)
System.Globalization
该名称空间包含的类用于全球化和本地化应用程序
System.IO
这是文件IO的名称空间,其中的类访问文件和目录,包括读取器、写入器和流
System.Net
这是核心网络功能的名称空间,比如访问DNS服务器,用System.Net.Sockets创建套接字
System.Threading
这是线程和任务的根名称空间。任务在System.Threading.Tasks中定义
Microsoft.Data
这是访问数据库的名称空间。Microsoft.Data.SqlClient包含访问SQL Server的类。以前包含在System.Data名称空间中的类已经被重新打包到Microsoft.Data中
Microsoft.Extensions.DependencyInjection
这是Microsoft依赖注入容器的名称空间,该依赖注入容器是.NET的一部分
Microsoft.EntityFrameworkCore
使用Entity Framework Core可以访问关系和NoSQL数据库。相关类型在这个名称空间中定义

1.3  .NET支持周期

        在.NET的新时代进行开发时,应该知道不同版本的支持周期。.NET发布版由Current(当前版本)或LTS(Long-Term Support,长期支持版本)标签区分。LTS版本至少支持3年,或者在下一个LTS版本发布后继续支持一年。例如,如果在一个LTS版本发布后,下一个LTS版本间隔2.5年再发布,则上一个LTS版本的支持时间为3.5年。当前发布版本在下一个版本发布后只会继续支持3个月。表1-2列出了不同.NET Core和.NET版本的发布日期、支持等级和结束支持日期。

从.NET5开始,版本变得更具有可预测性。每年11月将发布一个新的主版本。每隔一年发布的主版本是一个LTS版本。

根据工作环境,你可以选择使用LTS版本或当前版本。使用当前版本能够更快使用新特性,但需要更加频繁的升级到新版本。当应用程序还处在活跃的开发阶段时,你可能会决定使用当前版本。随着应用程序变得更加稳定,可以切换到下一个LTS版本。

     如果你已经使用持续集成/持续交付(continuous integration/continuous delivery,CI/CD)开始开发,则只使用当前版本、从而更快获得新特性就成为一项简单任务。

 

1.4  应用程序类型和技术

 1.4.1  数据访问

    在介绍应用程序类型之前,先看看所有应用程序类型在访问数据时都会采用的技术。

    文件和目录可以使用简单的API调用来访问,但简单的API调用对于有些场景而言不够灵活。使用流API有很大的灵活性,流提供了更多的特性,例如加密或压缩。读取器和写入器简化了流的使用。

    为了读取和写入数据库,可以使用抽象层:Entity  Framework  Core。Entity Framework Core提供了从对象层次结构到数据库关系的映射。EF Core不只能够使用不同的关系数据库,还支持NoSQL数据库,例如Azure Cosmos DB。

1.4.2  Windows应用程序

      对于创建Windows应用程序,可以使用新的UI控件WinUI 3.0来创建通用Windows平台(Universal Windows Platform,UWP)或Windows桌面应用程序。UWP应用程序使用沙盒环境,在这个沙盒环境中,应用程序需要根据使用的API向用户请求权限。桌面应用程序版本可以比作WPF和Windows Forms应用程序,它们可以使用几乎全部.NET 5 API。也可以更新WPF和Windows Form应用程序,使它们使用新的现代WinUI控件。

1.4.3 Web应用程序

        在使用.NET应用程序创建Web应用程序时,有多个选项可用。ASP.NET Core MVC这种技术为应用程序结构实现了模型-视图-控制器(Model-View-Controller,MVC)模式。如果你有一个.NET Framework ASP.NET MVC应用程序,那么转为使用ASP.NET Core MVC应该不会困难。

         相比MVC模式,ASP.NET Core Razor页面提供了一种更加简单的选项。Razor页面可以使用代码隐藏文件,或者将C#代码与HTML页面混合在一起。这种解决方案更容易上手,而且可以与MVC结合使用。Razor页面的依赖注入特性使得创建可重用的代码变得很容易。

         ASP.NET Core Blazor是一种新技术,用于消除JavaScript代码。它有一个服务器端变体,可以在服务器上处理用户界面事件。通过在后台使用signalR,客户端与服务器连接在一起。Blazor的另外一个变体是在客户端使用WebAssembly。有了这种变体,可以使用C#、HTML和CSS来编写代码,在客户端允许二进制文件。因为WebAssembly是一种HTML5标准,所以Blazor能够在所有现代浏览器中运行,并不需要使用插件。

        最初引入ASP.NET,从根本上改变了Web编程模型。ASP.NET Core再次改变了它,允许使用.NET Core提升性能和可伸缩性。它不只允许在Window上,也可以在Linux系统上运行。

        在ASP.NET Core中,不再包含ASP.NET Web Forms(它仍然可以使用,在.NET 4.7中更新)。

        ASP.NET Core MVC基于著名的MVC模式,更容易进行单元测试。它使用HTML,CSS,JavaScript编写用户界面,在后台使用C#,从而更好的实现了关注点分离。

1.4.4   服务

         SOAP和WCF在过去完成了它们的任务。现代应用程序则使用REST(representational  state transfer)和 Web API。使用ASP.NET Core创建Web API是一种更容易进行通信的选项,它满足了分布式应用程序90%以上的需求。这项技术是基于REST的,它为无状态、可伸缩的Web服务定义了指导方针和最佳实践。

         客户端可以接收JSON或XML数据。JSON和XML也可以被格式化,以使用Open Data(OData)规范。

         这个API的新特性使得在Web客户端上通过JavaScript、.NET和其他技术来使用它变得更加容易。

         创建Web API是构建微服务的好方法。构建微服务的方法定义了更小的服务,这些服务可以独立的运行和部署,可以自己控制数据存储。

         为了描述服务,定义了一个新的标准:OpenAPI。这个标准根植于Swagger。

         对于类似于远程过程调用(remote procedure calls,RPC)的通信,可以使用gRPC,它提供了一个基于HTTP/2的二进制通信,可在不同平台间使用。

1.4.5  SignalR

        对于实时Web功能以及客户端和服务器之间的双向通信,可以使用SignalR,它是一种ASP.NET Core技术。只要信息可用,SignalR就允许将信息尽快推送给连接的客户端。SignalR使用WebSocket技术推送信息。

1.4.6  Microsoft Azure

        现在,在考虑开发图景时不能忽视云。Microsoft Azure提供了软件即服务(Software as a Service,SaaS)、基础设施即服务(Infrastructure as a Service,IaaS),平台即服务(Platform as a Service,PaaS)和函数即服务(Function as a Service,FaaS)。有时产品介于这些类别之间。

       1. SaaS

       SaaS提供了完整的软件,不需要你处理服务器的管理和更新等。Office 365是一个SaaS产品,它通过云产品使用电子邮件和其他服务。与开发人员相关的SaaS产品是Azure DevOps Services。Azure DevOps Services是Azure DevOps Server(原来叫做Team Foundation Server)的云版本,可用于私有的和公共的代码仓库,跟踪错误和工作项,以及构建和测试服务。Microsoft提供的GitHub也属于这种类别,它使用Azure DevOps的许多特性进行了增强。

       2. IaaS

       另一个服务产品是IaaS。这个服务产品提供了虚拟机。用户负责管理操作系统,维护更新。当创建虚拟机时,可以决定使用不同的硬件产品,例如最多416核的共享核心。416核、11.4TB的RAM和8TB的本地SSD属于计算机的“M系列”。

      对于预装的操作系统,可以在Windows、Windows Server、Linux和预装了SQL Server、BizTalk Server、SharePoint和Oracle等许多产品的操作系统之间进行选择。

      如果想尝试在Linux上编译和运行.NET Core程序,但没有Linux计算机,在Microsoft Azure上安装这样一个环境是很容易的。

     3.PaaS

      对于开发人员来说,Microsoft Azure最相关的部分是PaaS。可以访问存储和读取数据的服务,使用应用程序服务的计算和联网功能,在应用程序中集成开发者服务。

      为了在云中存储数据,可以使用关系数据存储SQL Database。SQL Database与SQL Server的本地版本大致相同。也有一些NoSQL的解决方案(例如Cosmos DB),它们有不同的存储选项,如JSON数据、关系、表存储,以及存储blob(如图像或视频)的Azure Storage。

      应用程序服务可以用于托管通过ASP.NET Core创建的Web应用程序和API应用程序。

     除了前面介绍的Visual Studio Team Services,Microsoft Azure中的Developer Services的另一部分是Application Insights。它的发布周期更短,对于获得用户如何使用应用程序的信息越来越重要。哪些菜单会因为用户找不到而不被使用?用户在应用程序中使用什么路径来完成任务?在Application Insights中,可以得到有用的匿名用户信息,找出用户在使用应用程序时存在的问题,并使用DevOps快速解决这些问题。

     还可以使用Cognitive Services提供的功能处理图像,使用Bing Search API,利用语言服务理解用户的看法等。

     4.FaaS

     FaaS是云服务的一个新概念,也称为Azure无服务器计算技术。当然,幕后仍有一个服务器,只是不需要为保留的CPU和内存付费,就像在Web应用程序中使用的应用程序服务一样。相反,支付的金额是基于消费的,即基于调用次数计费,但对执行活动所需要的内存和时间有一些限制。Azure函数是一种可以使用FaaS进行部署的技术。

1.5  开发工具

       要进行开发,需要有一个SDK来生成和测试应用程序,还需要有一个代码编辑器。其他工具也会有帮助,例如Windows系统上的Linux环境,以及运行Docker镜像的环境。

1.5.1  .NET CLI

       要进行开发,需要安装.NET SDK。如果使用Visual Studio进行开发,则在安装Visual Studio的时候会安装.NET SDK。如果使用其他环境,或者想要安装与Visual Studio安装的版本不同的版本,那么可以访问https://dot.net。在这里,你可以为不同的平台下载和安装SDK的不同版本。

       SDK中包含.NET CLI,这是用于开发.NET 应用程序的命令行接口。你可以使用.NET CLI创建新的应用程序、编译应用程序、运行单元测试、创建NuGet包,以及创建在发布时需要的文件。除了使用.NET CLI,也可以使用任何编辑器(如记事本)来编写代码。当然,如果能够使用其他提供了智能感知功能的工具,那么使用那些工具将更易于运行和调试应用程序。

1.5.2  Visual Studio Code

       Visual Studio Code是一个轻量级编辑器,不只能够在Windows上使用,还可以在Linux和macOS上使用。Visual Studio社区创建了大量扩展,使得Visual Studio Code成为许多技术的首选环境。Visual Studio Code代码可以用于.NET Core控制台应用程序和ASP.NET Core Web应用程序的开发,但不能创建WinUI或Xamarin应用程序。可以从http://code.visualstudio.com下载Visual Studio Code。

1.5.3  Visual Studio Community

      这个版本的Visual Studio是免费的,具备以前Professional版的功能,但使用时间有许可限制。它对开源项目和培训、学术和小型专业团队是免费的。与Visual Studio Express版本(以前的免费版本)不同,Visual Studio Community允许在Visual Studio中使用扩展。

1.5.4  Visual Studio Professional

       这个版本比Community版包含更多功能,例如CodeLens和Team Foundation Server(用于进行源代码管理和团队协作)。有了这个版本,也会获得一个订阅,其中包括Microsoft提供的几个用于开发和测试的服务器产品,还会得到一个免费信用额度,可将其用于在Microsoft Azure中进行开发和测试。

1.5.5  Visual Studio Enterprise

       与Professional版不同,这个版本包含很多测试工具,如Live Unit Testing、Microsoft Fakes(用于单元测试隔离)和IntelliTest(单元测试是所有Visual Studio版本的一部分)。通过Code Clone可以找到解决方案中的相似代码。Visual Studio Enterprise版还包含架构和建模工具,以分析和验证解决方案架构。

注意:

有了Visual Studio 订阅,就有权每月免费使用一定数量的Microsoft Azure,具体数量由Visual Studio订阅的类型决定。

1.5.6  Visual Studio for Mac

         Visual Studio for Mac 起源于Xamarin Studio,但现在提供的功能比早期产品多得多。例如,Visual Studio for Mac的编辑器源代码与Windows版本的Visual Studio 相同。有了Visual Studio for Mac,不仅可以创建Xamarin应用程序,还可以创建在Windows、Linux和macOS上运行的ASP.NET Core应用程序。

1.5.7  Windows终端

        Windows命令提示在很多年间没有变化,如今终于有了一个全新的终端。该终端的源代码可在https://github.com/Microsoft/terminal访问,它提供了许多有助于开发的的特性。该终端提供了多个选项卡和不同的shell,例如Windows PowerShell(一个命令提示)、Azure Cloud Shell和WSL 2环境。该终端可以全屏显示,打开不同的选项卡以便于访问不同的文件夹,以及拆分窗格,从而拆分窗格,从而在一个屏幕中打开不同的文件夹进行比较。它每个月都在增加新的特性。可以从Microsoft Store安装终端。

1.5.8  WSL 2

       WSL 2是第二代Windows Subsystem for Linux。在这个版本中,运行Linux的子系统变得更快,而且提供了几乎所有Linux API。

       使用WSL 2可以从Microsoft Store安装不同的Linux发行版。如果使用Windows终端,则可以为安装的每个Linux发行版打开不同的选项卡。

       WSL 2是在Windows系统上的Linux环境中构建和运行.NET应用程序的一种简单方式。当.NET 应用程序在Linux环境中运行时,甚至可以使用Visual Studio调试它们,只需要安装了.NET Core Debugging with WSL 2扩展即可。在Visual Studio中运行调试会话的时候,会自动在WSL 2环境中安装.NET SDK。

1.5.9  Docker Desktop

        Docker Desktop for Linux(可以从https://hub.docker.com/editions/community/docker-ce-desktop-windows下载)允许为Linux或Windows允许Docker。使用Docker允许基于包含.NET运行库的镜像,创建包含应用程序代码的镜像。.NET允许库自身则基于Linux或Windows镜像。

       使用Docker时,可以使用在多个Docker容器内运行的许多.NET 服务创建解决方案。Docker容器是Docker镜像的运行实例,可以使用Visual Studio或dotnet工具(例如tye,其地址为https://github.com/dotnet/tye)创建。

1.6  使用.NET CLI

         许多时候并不需要Visual Studio,而可以使用任何编辑器和命令行(例如.NET CLI)。

         下面看看如何设置系统,以及如何使用这个工具。这里的介绍适用于所有平台。

          如今,CI/CD技术的应用,使得人们非常关注命令行。你可以创建一个管道,在后台自动进行编译、测试和部署。

          安装了.NET CLI工具后,就有了一个入口点来启动所有这些工具。使用下面的命令:

         >dotnet  --help

       会看到dotnet工具的所有不同的可用选项。许多选项都有简写形式。例如,对于上面的命令,也可以输入:

       >dotnet -h

1.6.1  创建应用程序

        dotnet工具提供了一种简单的方法创建“Hello World !”应用程序。输入如下命令就可以创建一个控制台应用程序:

>dotnet new console  --output  HelloWorld

       这个命令创建一个新的HelloWorld目录并添加源代码文件Program.cs和项目文件HelloWorld.csproj。dotnet new命令还包括dotnet restore的功能,所以所有必要的NuGet包都会下载。要查看应用程序使用的库的依赖项和版本列表,可以检查obj子目录中的文件project.assets.json。如果不适用选项--output(或简写形式-o),文件就在当前目录中生成。

生成的源代码如下所示:

using System;

namespace HelloWorld

{

   class Program

    {

      static void Main(string[  ]  args)

      {

         Console.WriteLine("Hello World !");

       }

    }

}

注意:20世纪70年代,《C程序设计语言》出版后,使用“Hello World”应用程序开始学习编程语言就变成一种传统。使用.NET CLI时,这个程序会自动生成。

下面看看这个程序的语法。Main( )方法是.NET应用程序的入口点。CLR在启动是调用静态Main( )方法。Main( )方法需要放到一个类中。这里,这个类命名为Program,但是可以给它指定任何名称。

      Console.WriteLine调用Console类的WriteLine( )方法。Console类在System名称空间中。为了避免在调用该方法时编写System.Console.WriteLine,在源文件的顶部使用using声明打开了System名称空间。

      在编写源代码之后,需要编译代码来运行它。

      创建的项目配置文件名为HelloWorld.csproj。该文件包含项目配置,例如目标框架,以及要创建的二进制文件的类型。该文件中有一条重要的信息,即对SDK的引用(项目文件HelloWorld/HelloWorld.csproj):

<Project Sdk="Microsoft.NET.Sdk">

   <PropertyGroup>

     <OutputType>Exe</OutputType>

     <TargetFramework>net5.0</TargetFramework>

   </PropertyGroup>

</Project>

1.6.2  顶级语句

      C# 9让我们能够简化“Hello World!”应用程序的代码。使用顶级语句时,可以去掉名称空间、类和Main( )方法声明,而只编写顶级语句。此时,“Hello World!”应用程序将如下所示:

using System;

Console.WriteLine("Hello World!");

如果为WriteLine( )方法调用添加System名称空间前缀,则可以把这个程序写成一行代码:

System.Console.WriteLine("Hello World!");

注意:

使用顶级语句时,仍然会在后台生成一个类和一个Main( )方法。查看生成的IL代码可知,生成了一个名为<Program>$的类,以及一个名为<Main>$的主方法,其中包含顶级语句。只不过不需要我们自己来编写这些代码。

对于示例应用程序等小型应用程序,顶级语句能够减少必须编写的代码。当在类似脚本的环境中使用C#时,顶级语句也很实用。

1.6.3  选择框架和语言版本

       除了为一个框架版本生成二进制文件,还可以选择将TargetFramework元素替换为TargetFrameworks,并指定多个框架,例如下面的代码中指定了.NET 5和.NET Framawork 4.8。添加LangVersion元素,是因为示例应用程序使用了C# 9代码(顶级语句)。如果不适用此特性,则框架版本将定义使用的C#版本。.NET 5默认使用C# 9,.NET Framework 4.8则使用C# 7.3。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFrameworks>net5.0;net48</TargetFrameworks>

    <LangVersion>9.0</LangVersion>

  </PropertyGroup>

</Project>

Sdk特性指定了项目使用的SDK。Microsoft提供了不同的SDK:Microsoft.NET.Sdk用于控制台应用程序,Microsoft.NET.Sdk.Web用于ASP.NET Core Web应用程序,Microsoft.NET.Sdk.BlazorWebAssembly用于使用Blazor和WebAssembly的Web应用程序。

      不需要手动把源文件添加到项目中。相同目录和子目录中,带有.cs扩展名的文件会自动添加到项目中进行编译。还会自动添加带有.resx扩展名的资源文件,用于嵌入资源。也可以改变默认行为,显示排除/包含文件。

       也不需要手动添加.NET Core包。当指定目标框架net5.0的时候,将自动包含元包Microsoft.NETCore.App,它引用了其它许多包。

1.6.4  构建应用程序

       要构建应用程序,需要将当前目录改为应用程序目录,并启动dotnet build。为.NET 5.0和.NET Framework 4.8编译时,输出如下:

>dotnet build

Microsoft (R) Build Engine version 16.8.0 for .NET Copyright (C)

Microsoft  Corporation.ALL rights reserved.

Determining projects to restore...

Restored C:\procsharp\Intro\HelloWorld\HelloWorld.csproj (in 308 ms).

HelloWorld -> C:\procsharp\Intro\HelloWorld\bin\Debug\net48\HelloWorld.exe

HelloWorld -> C:\procsharp\Intro\HelloWorld\bin\Debug\net5.0\HelloWorld.dll

Build succeeded.

0 Warning(s)

0 Error(s)

Time Elapsed 00:00:02:82

注意:命令dotnet new和dotnet build会自动恢复NuGet包,这可以防止忘记恢复包。恢复NuGet包的操作会从NuGet服务器或者环境中配置的其它服务器获取项目文件中引用的库。也可以使用dotnet restore显式的恢复NuGet包。

   

      编译过程的结果是在bin/debug/[net5.0|net48]文件夹中生成一个程序集,其中包含Program类的IL代码。如果比较.NET Core与.NET 4.8的构建结果,会发现对于.NET Core,生成了一个包含IL代码的DLL,而对于.NET 4.8,生成一个包含IL代码的EXE。为.NET Core生成的程序集依赖于System.Console程序集,而.NET 4.8程序集则在mscorlib程序集中包含Console类。

      要构建发布代码,就需要指定选项--configuration Release(简写为-c Release):

  >dotnet build --configuration Release

注意:

调试构建包含调试符号,并且为了方便调试,并没有对生成的代码进行优化。而在发布构建中,针对生产环境优化了代码,所以代码运行更快。在开发阶段(即把应用程序交付到生产环境之前),应该时不时试用发布构建,因为其行为可能与调试构建存在区别。

1.6.5 运行应用程序

要运行应用程序,可以使用dotnet run命令。

>dotnet run

如果项目文件面向多个框架,就需要通过--framework选项告诉dotnet run命令,使用哪个框架来运行应用程序。这个框架必须通过csproj文件来配置。对于样例应用程序,可以在恢复信息之后得到如下输出:

>dotnet run --framework net5.0

Hello World!

在生产系统中,不适用dotnet run运行应用程序,而是使用dotnet和库的名称:

>dotnet bin/debug/net5.0/HelloWorld.dll

   编译器还会创建可执行文件,但它的作用只是加载和启动库。也可以启动可执行文件。接下来的步骤将说明如何为发布应用程序构建可执行文件。

注意:

前面是在Windows上构建和运行“Hello World!”应用程序,而dotnet工具在Linux和macOS上的工作方式是相同的。可以在这两个平台上使用相同的.NET CLI命令。

1.6.6 创建Web应用程序

       与创建控制台应用程序类似,也可以使用.NET CLI创建Web应用程序。输入dotnet new时,可以看到可用的模板列表。

下面的命令:

>dotnet new webapp -o WebApp

会使用Razor Pages创建新的ASP.NET Core Web应用程序。

创建的项目文件现在包含对Microsoft.NET.Sdk.Web SDK的引用。该SDK包含创建Web应用程序和服务时需要用到的工具和扩展:

<Project Sdk="Microsoft.NET.Sdk.Web">

   <PropertyGroup>

     <TargetFramework>5.0</TargetFramework>

   </PropertyGroup>

</Project>

现在使用下述命令:

>dotnet build

>dotnet run

运行上述代码会启动ASP.NET Core的Kestrel服务器,来监听端口5000和5001。可以打开浏览器访问从这个服务器返回的页面,如图1-2所示。

如果是第一次启动该服务器,会收到一个安全警告,询问是否信任开发人员证书。选择信任后,将不再显示该警告。

要停止应用程序,只需按Ctrl+C来发出取消命令。

1.6.7  发布应用程序

      使用dotnet工具,可以创建一个NuGet包并发布应用程序来进行部署。首先创建应用程序的依赖于框架的部署。这减少了发布所需的文件。

      使用之前创建的控制台应用程序,只需要运行以下命令来创建发布所需的文件。使用-f选择框架,使用-c选择发布配置。

     >dotnet publish -f net5.0 -c  Release

发布所需的文件放在bin/Release/net5.0/publish 目录中。

在目标系统上使用这些文件进行发布时,也需要运行库。在https://www.microsoft.com/net/download/上可以找到运行库的下载和安装说明。

注意:

如果应用程序使用了额外NuGet包,这些包需要在csproj文件中引用,并且库需要与应用程序一起交付。

1.6.8  自包含部署

        也可以不在目标系统上安装运行库,而是在交付应用程序时一起交付运行库。这就是所谓的自包含部署。

        安装应用程序的平台不同,运行库就不同。因此,对于自包含部署,需要通过在项目文件中指定RuntimeIdentifiers,来指定支持的平台,如下面的项目文件所示。这里,指定了Windows10、macOS和Ubuntu Linux的运行库标识符:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>net5.0</TargetFramework>

  </PropertyGroup>

  <PropertyGroup>

    <RuntimeIdentifiers>

      win10-x64; ubuntu-x64; osx.10.11-x64;

    </RuntimeIdentifiers>

  </PropertyGroup>

</Project>

注意:

在https://docs.microsoft.com/en-us/dotnet/core/rid-catalog的.NET Core Runtime Identifier(RID)类别中,可以获取不同平台和版本的所有运行库标识符。

现在可以为所有不同的平台创建发布文件:

>dotnet publish -c Release -r win10-x64

>dotnet publish -c Release -r osx.10.11-x64

>dotnet publish -c Release -r ubuntu-x64

在运行这些命令之后,可以在Release/[win10-x64|osx.10.11-x64|ubuntu-x64]/publish目录中找到发布所需要的文件。因为现在包含.NET 5.0运行库,所以发布需要的文件的规模也越来越大。在这些目录中,可以找到平台特定的可执行文件,可以在不使用dotnet命令的情况下直接启动它。

注意:

如果运行安装了WSL 2的Windows系统,则可以在该子系统中直接运行Ubuntu创建的二进制文件镜像。如果在WSL中安装了.NET SDK,则也可以在该子系统内执行构建和发布命令。

1.6.9  创建单个可执行文件

       除了发布大量文件,也可以创建单个可执行文件。添加-p:PublishSingleFile=true选项,会把整个运行库添加到一个二进制文件中,然后可以将该文件用于部署。运行下面的命令,将在输出目录singlefile中创建一个文件。该目录还包含一个带有.pdb扩展名的文件。可以部署该文件来获取符号信息,以便在应用程序崩溃时能够进行分析。

>dotnet publish -r win10-x64  -p:PublishSingleFile=true --self-contained

-o  singlefile

1.6.10   readytorun

         为了提高应用程序的启动性能,可以将应用程序的一部分编译为原生代码。这样一来,在运行应用程序的时候,IL编译器要要做的工作就减少了。无论有没有使用PublishSingleFile,都可以使用这个选项。

>dotnet publish -r win10-x64  -p:PublishReadyToRun=true  --self-contained

-o readytorun

除了使用命令行传递此配置,还可以在项目文件中指定<PublishReadyToRun>元素。

1.6.11  剪裁

       当然,发布应用程序时,在一个可执行文件中包含完整的运行库会导致文件太大。可以通过这种方法解决:剪裁掉应用程序不需要的类和方法,使二进制文件变得更小。

       通过在项目文件中指定PublishTrimmed元素,可以启用剪裁。TrimMode指定了剪裁的程度。值link(本例中使用了这个值)基于成员进行剪裁,删除掉未使用的成员。当把这个值设置为copyused的时候,如果应用程序使用了一个程序集中的任何成员,就完整保留该程序集:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>

      <OutputType>Exe<OutputType>

      <TargetFramework>net5.0</TargetFramework>

      <RuntimeIdentifiers>

        win10-x64;ubuntu-x64;osx.10.11-x64;

      </RuntimeIdentifiers>

      <PublishTrimmed>true</PublishTrimmed>

      <TrimMode>link</TrimMode>

  </PropertyGroup>

</Project>

通过使用下面的命令和上面的项目配置,可以创建一个应用了剪裁的可执行文件。

>dotnet publish -o publishtrimmed -p:PublishSingleFile=true --self-contained

-r win10-x64

剪裁存在风险。例如,如果应用程序使用了反射,那么剪裁器不知道运行时需要反射成员。为了应对这种问题,可以指定不剪裁哪些程序集、类型和类型成员。要配置这些选项,请在以下网址阅读详细的文档:https://docs.microsoft.com/dotnet/core/deploying/trimming-options。

1.7 小结
本章涵盖了很多重要的技术和.NET的变化。在将来的开发中,应该使用.NET Core(现在已经重命名为.NET)创建新的应用程序。对于现有应用程序,无论是想继续使用老技术,还是迁移到新技术,都要视应用程序的状态而定。如果想迁移到.NET,那么现在你已经知道了可以使用什么框架来替换旧框架。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GiselleLu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值