次の方法で共有


ASP.NET Core 要求デリゲート ジェネレーターを使用して Map メソッドを要求デリゲートに変換する

ASP.NET Core 要求デリゲート ジェネレーター (RDG) はコンパイル時ソース ジェネレーターであり、最小 API に提供されたルート ハンドラーを、ASP.NET Core のルーティング インフラストラクチャによって処理できる要求デリゲートにコンパイルします。 RDG は、AoT が有効な状態でアプリケーションが発行されたとき、またはトリミングが有効になっている場合に暗黙的に有効になります。 RDG では、トリミングとネイティブの AoT フレンドリ コードが生成されます。

Note

  • ネイティブ AOT の機能は現在プレビュー段階です。
  • .NET 8 では、すべての ASP.NET Core 機能がネイティブ AOT と互換性を持つわけではありません。

RDG では、次のことが行われます。

発行時にネイティブ AOT が有効では ない 場合:

  • 特定のルートに関連付けられている Map メソッドは、アプリのビルド時ではなくアプリの開始時に、メモリ内で要求デリゲートにコンパイルされます。
  • 要求デリゲートは実行時に生成されます。

発行時にネイティブ AOT が有効である場合:

  • 特定のルートに関連付けられている Map メソッドは、アプリのビルド時にコンパイルされます。 RDG によってルートの要求デリゲートが作成され、要求デリゲートはアプリのネイティブ イメージにコンパイルされます。
  • 実行時に要求デリゲートを生成する必要がなくなります。
  • 次のことが保証されます。
    • アプリの API で使われる型は、ネイティブ AOT ツール チェーンによって静的に分析される方法で、アプリのコードから生成されます。
    • 必要なコードがトリミングされることはありません。

RDG では、次のことが行われます。

  • ネイティブ AOT を使った発行が有効になっているか、トリミングが有効になっている場合、プロジェクトで自動的に有効になります。
  • ネイティブ 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 を手動で有効にすると、次の場合に役立ちます。

  • ネイティブ 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 はネイティブ AOT でサポートされていないシナリオに対して診断を生成します。 診断は警告として生成され、アプリのビルドを妨げることはありません。 診断の一覧については、ASP.NET Core 要求デリゲート ジェネレーターの診断に関するページをご覧ください。