使用.NET 6开发TodoList应用(1)——系列背景
前言
想到要写这样一个系列博客,初衷有两个:一是希望通过一个实践项目,将.NET 6 WebAPI开发的基础知识串联起来,帮助那些想要入门.NET 6服务端开发的朋友们快速上手,对使用.NET 6开发后端服务的技术全貌有一个基本的认识和掌握,顺便把自己的技能树检查一遍;二是希望为国内的.NET环境有一些小小的帮助,最早我自己是做C#桌面应用出身的,但是随着互联网产业的繁盛和微软早年间的固执,使得国内的.NET开发环境收缩到几个固定的领域,以致于很多人今天依然认为C#和.NET不适合做大型的企业级应用,这个观念需要改变了。我无意比较技术和语言之间的好坏,只是更愿意看到国内的技术环境也能呈现出百家争鸣的状态。经过微软这么多年的改变和进步,.NET 6是一个很优秀的框架,这一点自从我最开始接触.NET Core 2起一年一年进化到现在,就深切地感受到,那好东西就拿出来和大家分享一下。
系列说明
在这个系列博客中,我将会使用.NET 6从头开始一步一步开发一个TodoList单体应用,在这个过程中尽可能将多的知识点独立成每篇文章,最后将应用通过Docker进行打包,并使用Github的Action和Azure Container Instance服务实现CI/CD。
选择TodoList的原因是这个项目足够简单,但是也足够去覆盖我希望覆盖到的知识点,对于读者来说,有以下一些建议的前置要求:
- 需要会写C#,不需要.NET (Core)相关的开发经验。
- 需要后端服务的开发经验,对基本的服务端相关特性有一定的认识。
- 有对Clean Architecture的基本理解。
从下一篇文章开始,我们将从需求入手,通过大概30篇左右的文章来实现这个TodoList应用。
- 使用.NET 6开发TodoList应用(1)——系列背景
- 使用.NET 6开发TodoList应用(2)——项目结构搭建
- 使用.NET 6开发TodoList应用(3)——引入第三方日志
- 使用.NET 6开发TodoList应用(4)——引入数据存储
- 使用.NET 6开发TodoList应用(5.0)——领域实体创建和配置
- 使用.NET 6开发TodoList应用(5.1)——实现CQRS模式
- 使用.NET 6开发TodoList应用(5.2)——实现AutoMapper
- 使用.NET 6开发TodoList应用(6)——实现POST请求
- 使用.NET 6开发TodoList应用(7)——实现GET请求
- 使用.NET 6开发TodoList应用(8)——实现全局异常处理
- 使用.NET 6开发TodoList应用(9)——实现PUT请求
- 使用.NET 6开发TodoList应用(10)——实现PATCH请求
- 使用.NET 6开发TodoList应用(11)——HTTP请求幂等性的考虑
- 使用.NET 6开发TodoList应用(12)——实现接口请求验证
- 使用.NET 6开发TodoList应用(13)——实现ActionFilter
- 使用.NET 6开发TodoList应用(14)——实现查询分页
- 使用.NET 6开发TodoList应用(15)——实现查询过滤
- 使用.NET 6开发TodoList应用(16)——实现查询搜索
- 使用.NET 6开发TodoList应用(17)——实现查询排序
- 使用.NET 6开发TodoList应用(18)——实现数据塑形
- 使用.NET 6开发TodoList应用(19)——实现HATEAOS支持
- 使用.NET 6开发TodoList应用(20)——处理OPTION和HEAD请求
- 使用.NET 6开发TodoList应用(21)——实现Root Document
- 使用.NET 6开发TodoList应用(22)——实现API版本控制
- 使用.NET 6开发TodoList应用(23)——实现缓存
- 使用.NET 6开发TodoList应用(24)——实现请求限流和阈值控制
- 使用.NET 6开发TodoList应用(25)——实现基于JWT的Identity功能
- 使用.NET 6开发TodoList应用(26)——实现RefreshToken
- 使用.NET 6开发TodoList应用(27)——实现Configuration和Option的强类型绑定
- 使用.NET 6开发TodoList应用(28)——实现API的Swagger文档化
- 使用.NET 6开发TodoList应用(29)——实现应用程序健康检查
- 使用.NET 6开发TodoList应用(30)——实现本地化功能
- 使用.NET 6开发TodoList应用(31)——实现Docker打包和部署
- 使用.NET 6开发TodoList应用(32)——实现基于Github Actions和ACI的CI/CD
附:.NET 6 Web API项目代码上的变化
创建项目
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
.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();
Change 1: Top-level statements
顶级声明使得我们在编写Program类时可以不用再定义该类,省略Main函数定义,直接开始写方法体。编译器会在编译阶段为我们自动加上命名空间和相关定义。
Change 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>
Change 3: No Startup class
到了.NET 6,陪伴我们好几个版本至今的ConfigureServices
and Configure
方法终于消失了,取而代之的是这两部分的配置都集中在了Program.cs
中。曾经写过.NET Core WebAPI
的小伙伴不难看出来现在应该写在哪里。
对于一些大型项目来说,这两部分我们肯定不能就这样写在Program.cs
里面,后面将会想办法把这两部分单独拆开进行配置。
当然,老版本的含有Startup.cs
的项目在.NET 6下打开没有任何问题。
关于Pipeline的一些知识点
Pipeline Sequence
- ExceptionHandler
- HSTS
- HttpsRedirection
- Static Files
- Routing
- CORS
- Authentication
- Authorization
- Custom Middlewares
- Endpoint Configuration
app.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);
app.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
,允许应用程序以这种形式响应客户端的请求,在快速构建微服务应用的过程中十分好用,在这个系列里,因为构建的是一个单体应用,这部分知识点我打算放到第二个系列关于微服务开发实践中去,看有没有更合适的场景去展示。
使用.NET 6开发TodoList应用(1)——系列背景的更多相关文章
- 使用.NET 6开发TodoList应用(3)——引入第三方日志库
需求 在我们项目开发的过程中,使用.NET 6自带的日志系统有时是不能满足实际需求的,比如有的时候我们需要将日志输出到第三方平台上,最典型的应用就是在各种云平台上,为了集中管理日志和查询日志,通常会选 ...
- 使用.NET 6开发TodoList应用(2)——项目结构搭建
为了不影响阅读的体验,我把系列导航放到文章最后了,有需要的小伙伴可以直接通过导航跳转到对应的文章 : P TodoList需求简介 首先明确一下我们即将开发的这个TodoList应用都需要完成什么功能 ...
- 使用.NET 6开发TodoList应用(4)——引入数据存储
需求 作为后端CRUD程序员(bushi,数据存储是开发后端服务一个非常重要的组件.对我们的TodoList项目来说,自然也需要配置数据存储.目前的需求很简单: 需要能持久化TodoList对象并对其 ...
- 使用.NET 6开发TodoList应用(5)——领域实体创建
需求 上一篇文章中我们完成了数据存储服务的接入,从这一篇开始将正式进入业务逻辑部分的开发. 首先要定义和解决的问题是,根据TodoList项目的需求,我们应该设计怎样的数据实体,如何去进行操作? 长文 ...
- 使用.NET 6开发TodoList应用(5.1)——实现Repository模式
需求 经常写CRUD程序的小伙伴们可能都经历过定义很多Repository接口,分别做对应的实现,依赖注入并使用的场景.有的时候会发现,很多分散的XXXXRepository的逻辑都是基本一致的,于是 ...
- 使用.NET 6开发TodoList应用(6)——使用MediatR实现POST请求
需求 需求很简单:如何创建新的TodoList和TodoItem并持久化. 初学者按照教程去实现的话,应该分成以下几步:创建Controller并实现POST方法:实用传入的请求参数new一个数据库实 ...
- 使用.NET 6开发TodoList应用文章索引
系列导航 使用.NET 6开发TodoList应用(1)--系列背景 使用.NET 6开发TodoList应用(2)--项目结构搭建 使用.NET 6开发TodoList应用(3)--引入第三方日志 ...
- 使用.NET 6开发TodoList应用(7)——使用AutoMapper实现GET请求
系列导航 使用.NET 6开发TodoList应用文章索引 需求 需求很简单:实现GET请求获取业务数据.在这个阶段我们经常使用的类库是AutoMapper. 目标 合理组织并使用AutoMapper ...
- 使用.NET 6开发TodoList应用(8)——实现全局异常处理
系列导航 使用.NET 6开发TodoList应用文章索引 需求 因为在项目中,会有各种各样的领域异常或系统异常被抛出来,那么在Controller里就需要进行完整的try-catch捕获,并根据是否 ...
随机推荐
- [luogu5577]算力训练
(以下以$B$为进制,$m$为幂次,$n=B^{m}$) 定义$\oplus$为$k$进制下不进位加法,$\otimes$为$\oplus$卷积 令$f_{i,j}$表示前$i$个数的$\oplus$ ...
- [atARC096F]Sweet Alchemy
给定一棵有根树,记$f_{i}$表示$i$的父亲,每一个点有一个代价$c_{i}$ 给定常数$D$和$X$,再给每个点赋一个权值$v_{i}$($v_{i}\ge 0$),满足以下条件下最大化$\su ...
- Furion分表分库我也要happy coding
Furion分表分库集成ShardingCore ShardingCore ShardingCore 易用.简单.高性能.普适性,是一款扩展针对efcore生态下的分表分库的扩展解决方案,支持efco ...
- sb 错误
数组开小.很容易 \(2 \times 10^5\) 或 \(10^6\) 就开成 \(10^5\),或者各种变量的数据范围混用,\(m \leq 5\times 10^5\),结果只开到了 \(n\ ...
- 洛谷 P4516 [JSOI2018]潜入行动
题面传送门 一眼树形 \(dp\) 本题有 \(2\) 大难点. 难点之一是状态的设计,这里需要四维状态,\(dp[i][j][0/1][0/1]\) 表示在以 \(i\) 为根的子树内放了 \(j\ ...
- NOIP2021 游记
不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分不要挂分释迦牟尼脚绽莲花菩提达摩你真伟大天上天下唯我独尊如来佛祖太上老君耶稣耶稣 ...
- NCBI SRA数据如何进行md5校验?
下了一些sra数据库中的公共数据,因为pretech和aspera不稳定,稍微大点的文件经常传断,部分文件我只能通过本地下载再上传. 那么问题来了,sra没有md5校验,我怎么知道我数据的完整性,尤其 ...
- 【百奥云GS专栏】全基因组选择之工具篇
目录 1. 免费开源包/库 1.1 R包 1.2 Python库 2. 成熟软件 3. WEB/GUI工具 前面我们已经介绍了基因组选择的各类模型,今天主要来了解一下做GS有哪些可用的软件和工具.基因 ...
- Perl语言编程(大骆驼)
啰嗦几句 Perl的时代已经过去,现在年轻的同事们基本上都在用Python了.但个人认为单就生物信息文本处理而言,Perl语言是绝对够用的.最主要的是,前辈们搭建的流程大多数是Perl写的,因此,如果 ...
- cp -拷贝文件出现错误
对于cp -a最主要的用法是在保留原文件属性的前提下复制文件. 如果出现了拷贝文件错误,在文件前面加上-a 即可