Minimal API - 创建项目

452 阅读2分钟

创建

打开vs,创建项目选择 ASP.NET Core Web API(native AOT),既然都用上了minimal api 追求轻巧,那就贯彻到底。

image.png

一定要选择顶级语句。

image.png

那以上的步骤可以直接使用如下的命令行完成。

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请求文件,之前在vscodeREST Client插件中使用过。

image.png

发布

取消勾选生成单个文件这个和AOT有冲突,其他的随意。命令行可以使用dotnet publish

image.png

最终的程序大小为9M左右,但这只是空项目。

image.png

总结

  1. CreateSlimBuilder
    对原有的CreateBuilder做出修剪,以支持AOT,当然好处就是发布的体积变小。以下为不支持的内容 原文链接

  2. AppJsonSerializerContext 这个类继承了抽象类JsonSerializerContext,本来是需要实现抽象方法的,但在本例代码中并未实现,这都归功于Source Generator。使用vs打开解决方案 > 项目 > 依赖项 > 分析器 > System.Text.Json.SourceGeneration > System.Text.Json.SourceGeneration.JsonSourceGenerator 此时我们可以看到分析器帮我们生成了许多代码,但作为代价,需要创建一个分部类并添加Attribute标记类型自动创建json序列化代码。

image.png