.NET 6开发TodoList应用实现系列背景
前言:
想到要写这样一个系列博客,初衷有两个:一是希望通过一个实践项目,将.NET 6 WebAPI开发的基础知识串联起来,帮助那些想要入门.NET 6服务端开发的朋友们快速上手,对使用.NET 6开发后端服务的技术全貌有一个基本的认识和掌握,顺便把自己的技能树检查一遍;二是希望为国内的.NET环境有一些小小的帮助,最早我自己是做C#桌面应用出身的,但是随着互联网产业的繁盛和微软早年间的固执,使得国内的.NET开发环境收缩到几个固定的领域,以致于很多人今天依然认为C#和.NET不适合做大型的企业级应用,这个观念需要改变了。我无意比较技术和语言之间的好坏,只是更愿意看到国内的技术环境也能呈现出百家争鸣的状态。经过微软这么多年的改变和进步,.NET 6是一个很优秀的框架,这一点自从我最开始接触.NET Core 2
起一年一年进化到现在,就深切地感受到,那好东西就拿出来和大家分享一下。
1.列说明
在这个系列博客中,我将会使用.NET 6从头开始一步一步开发一个TodoList
单体应用,在这个过程中尽可能将多的知识点独立成每篇文章,最后将应用通过Docker
进行打包,并使用Github
的Action
和Azure Container Instance
服务实现CI/CD。
选择TodoList的原因是这个项目足够简单,但是也足够去覆盖我希望覆盖到的知识点,对于读者来说,有以下一些建议的前置要求:
- 需要会写C#,不需要.
NET (Core)
相关的开发经验。 - 需要后端服务的开发经验,对基本的服务端相关特性有一定的认识。
- 有对
Clean Architecture
的基本理解。
2.系列导航
2.1 使用.NET 6开发TodoList应用文章索引
附:.NET 6 Web API项目代码上的变化
2.1.1创建项目
mkdir ProjectName && cd ProjectName dotnet new sln -n SampleApi dotnet new project -f net6.0 -n SampleApi -o SampleApi dotnet sln SampleApi.sln add SampleApi/SampleApi.csproj dotnet restore dotnet run -p SampleApi/SampleApi.csproj
2.1.2.NET 6 WebAPI Program.cs的变更
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
2.1.3Change 1: Top-level statements
顶级声明使得我们在编写Program
类时可以不用再定义该类,省略Main函数定义,直接开始写方法体。编译器会在编译阶段为我们自动加上命名空间和相关定义。
2.1.4Change 2: Implicit using directives
隐式using
指令是编译器根据项目类型,在编译阶段自动生成一个名为CompanyEmployees.GlobalUsings.g.cs
的文件,
内容如下:
// <auto-generated/> global using global::Microsoft.AspNetCore.Builder; global using global::Microsoft.AspNetCore.Hosting; global using global::Microsoft.AspNetCore.Http; global using global::Microsoft.AspNetCore.Routing; global using global::Microsoft.Extensions.Configuration; global using global::Microsoft.Extensions.DependencyInjection; global using global::Microsoft.Extensions.Hosting; global using global::Microsoft.Extensions.Logging; global using global::System; global using global::System.Collections.Generic; global using global::System.IO; global using global::System.Linq; global using global::System.Net.Http; global using global::System.Net.Http.Json; global using global::System.Threading; global using global::System.Threading.Tasks;
也可以在CompanyEmployees.csproj
工程配置文件中修改以下属性,禁用全局隐式using
指令这一特性:
<!-- <ImplicitUsings>enable</ImplicitUsings> --> <ImplicitUsings>disable</ImplicitUsings>
2.1.5Change 3: No Startup class
到了.NET 6,陪伴我们好几个版本至今的ConfigureServices and Configure
方法终于消失了,取而代之的是这两部分的配置都集中在了Program.cs
中。曾经写过.NET Core WebAPI
的小伙伴不难看出来现在应该写在哪里。
对于一些大型项目来说,这两部分我们肯定不能就这样写在Program.cs
里面,后面将会想办法把这两部分单独拆开进行配置。
当然,老版本的含有Startup.cs
的项目在.NET 6下打开没有任何问题。
2.2 关于Pipeline的一些知识点
2.2.1Pipeline Sequence
- ExceptionHandler
- HSTS
- HttpsRedirection
- Static Files
- Routing
- CORS
- Authentication
- Authorization
- Custom Middlewares
- Endpoint Configuration
2.2.2app.Run和app.Use
app.Run
用于终止Pipeline
的链式调用并向客户端返回
public static void Run(this IApplicationBuilder app, RequestDelegate handler); public delegate Task RequestDelegate(HttpContext context);
app.Use
用于向Pipeline
中插入一段逻辑作为链式调用的其中一个环节
public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware);
2.2.3app.Map和app.MapWhen
这两个方法都是用于在middleware
的链式调用中进行分支Pipeline
调用链处理。
public static IApplicationBuilder Map(this IApplicationBuilder app, PathString pathMatch, Action<IApplicationBuilder> configuration) public static IApplicationBuilder MapWhen(this IApplicationBuilder app, Func<HttpContext, bool> predicate, Action<IApplicationBuilder> configuration)
app.MapGet、app.MapPost、app.MapPut、app.Delete、app.MapMethods
在.NET 6中一个新增的特性叫做Minimal APIs
,允许应用程序以这种形式响应客户端的请求,在快速构建微服务应用的过程中十分好用,在这个系列里,因为构建的是一个单体应用,这部分知识点我打算放到第二个系列关于微服务开发实践中去,看有没有更合适的场景去展示。