创建
打开vs,创建项目选择 ASP.NET Core Web API(native AOT),既然都用上了minimal api 追求轻巧,那就贯彻到底。
一定要选择顶级语句。
那以上的步骤可以直接使用如下的命令行完成。
dotnet new webapiaot -n <ProjectName> -o <DirName>
代码解析
首先看一下项目文件, PublishAot标记了该项目发布为AOT模式
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<PublishAot>true</PublishAot>
</PropertyGroup>
</Project>
以下为项目自带的代码,以标明注释
using System.Text.Json.Serialization;
// 创建一个web程序主机构造器
var builder = WebApplication.CreateSlimBuilder(args);
// 配置http请求json序列化
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
// 创建web主机
var app = builder.Build();
// 模拟数据仓储
var sampleTodos = new Todo[]
{
new(1, "Walk the dog"),
new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)),
new(3, "Do the laundry", DateOnly.FromDateTime(DateTime.Now.AddDays(1))),
new(4, "Clean the bathroom"),
new(5, "Clean the car", DateOnly.FromDateTime(DateTime.Now.AddDays(2))),
};
// 创建路由分组
var todosApi = app.MapGroup("/todos");
// 映射GET请求,并完成请求体。获取所有todo数据
todosApi.MapGet("/", () => sampleTodos);
// 映射GET请求,并完成请求体。使用路由参数模型绑定id,获取id对应的todo数据
todosApi.MapGet(
"/{id}",
(int id) =>
sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
? Results.Ok(todo)
: Results.NotFound()
);
// 启动主机
app.Run();
// 定义模型
public record Todo(int Id, string? Title, DateOnly? DueBy = null, bool IsComplete = false);
// 注册json序列化代码
// 这里是AOT的体现,由于正常的序列化操作会引入大量的反射操作,在生成aot代码时不被支持。
// 微软引入源生成器(Source Generator)功能解决这个问题
// 这个之后在说
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext { }
启动
在vs中点击启动按钮,或者使用快捷键F5,在vscode中使用命令行工具输入 dotnet run 或者配置调试后使用 F5。
我目前的dotnet模板生成的项目中带有http请求文件,之前在vscode的 REST Client插件中使用过。
发布
取消勾选生成单个文件这个和AOT有冲突,其他的随意。命令行可以使用dotnet publish。
最终的程序大小为9M左右,但这只是空项目。
总结
-
CreateSlimBuilder
对原有的CreateBuilder做出修剪,以支持AOT,当然好处就是发布的体积变小。以下为不支持的内容 原文链接 -
AppJsonSerializerContext这个类继承了抽象类JsonSerializerContext,本来是需要实现抽象方法的,但在本例代码中并未实现,这都归功于Source Generator。使用vs打开解决方案 >项目> 依赖项 > 分析器 >System.Text.Json.SourceGeneration>System.Text.Json.SourceGeneration.JsonSourceGenerator此时我们可以看到分析器帮我们生成了许多代码,但作为代价,需要创建一个分部类并添加Attribute标记类型自动创建json序列化代码。