使用 ASP.NET Core 请求委托生成器将映射方法转换为请求委托

ASP.NET Core 请求委托生成器 (RDG) 是一种编译时源生成器,可编译提供给最小 API 的路由处理程序,以请求可由 ASP.NET Core 路由基础结构处理的委托。 在启用 AoT 的情况下发布应用程序时或启用了剪裁时,将隐式启用 RDG。 RDG 生成剪裁和本机 AoT 友好代码。

注意

  • Native AOT 功能当前为预览版。
  • 在 .NET 8 中,并非所有 ASP.NET Core 功能都与 Native AOT 兼容。

RDG:

在未启用 Native AOT 的情况下发布时:

  • 与特定路由关联的 Map 方法在应用启动时(而不是应用生成时)在内存中编译为请求委托。
  • 请求委托在运行时生成。

在启用了 Native AOT 的情况下发布时:

  • 与特定路由关联的 Map 方法在应用生成时编译。 RDG 会为路由创建请求委托,并将请求委托编译到应用的本机映像中。
  • 无需在运行时生成请求委托。
  • 确保:
    • 应用 API 中使用的类型以 Native AOT 工具链可静态分析的方式植根于应用代码中。
    • 不需要剪裁所需的代码。

RDG:

  • 会在项目中自动启用(在启用本机 AOT 的情况下发布时或启用了剪裁时)。
  • 即使不使用 Native AOT,也可以通过在项目文件中设置 <EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator> 来手动启用:
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator>
  </PropertyGroup>
    
</Project>

手动启用 RDG 对于以下场景很有用:

  • 评估项目与 Native AOT 的兼容性。
  • 通过预生成请求委托来减少应用的启动时间。

最小 API 已针对使用 System.Text.Json 进行了优化,这需要使用 System.Text.Json 源生成器。 在最小 API 中作为请求委托的参数或从请求委托返回的参数而被接受的所有类型都必须在通过 ASP.NET Core 的依赖项注入注册的 JsonSerializerContext 上进行配置:

using System.Text.Json.Serialization;

var builder = WebApplication.CreateSlimBuilder(args);

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(
                         0, AppJsonSerializerContext.Default);
});

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");
todosApi.MapGet("/", () => sampleTodos);
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);

[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

对不支持的 RDG 方案的诊断

生成应用后,RDG 会针对 Native AOT 不支持的方案发出诊断信息。 诊断作为警告发出,不会阻止应用生成。 有关诊断信息列表,请参阅 ASP.NET Core 请求委托生成器诊断