ネイティブ AOT の ASP.NET Core サポート
ASP.NET Core 8.0 では、.NET ネイティブ Ahead-Of-Time (AOT) のサポートが導入されています。
この記事のガイダンスに追加されるまたは優先する Blazor WebAssembly ネイティブ AOT のガイダンスについては、「ASP.NET Core Blazor WebAssembly ビルド ツールと事前 (AOT) コンパイル」をご覧ください。
ASP.NET Core でネイティブ AOT を使う理由
ネイティブ AOT アプリを発行およびデプロイすることには、次の利点があります。
- ディスク占有領域を最小限に抑える: ネイティブ AOT を使って発行すると、プログラムをサポートするために必要な外部依存関係のコードのみを含む 1 つの実行可能ファイルが生成されます。 実行可能ファイルのサイズ削減は、次につながります。
- より小さいコンテナー イメージ (たとえば、コンテナー化されたデプロイのシナリオで)。
- より小さいイメージからデプロイ時間を短縮する。
- 起動時間の短縮: ネイティブ AOT アプリケーションでは、起動時間が短縮される可能性があります。つまり、次のことが言えます。
- より迅速にアプリが要求を処理する準備が整う。
- アプリのあるバージョンから別のバージョンへの移行をコンテナー オーケストレーターで管理する必要がある場合、デプロイが改善される。
- 必要なメモリの削減: ネイティブ AOT アプリでは、アプリによって実行される作業に応じて、必要なメモリを減らすことができます。 メモリ消費量が減ると、デプロイの密度が高くなり、スケーラビリティが向上する可能性があります。
テンプレート アプリは、AOT 公開アプリ、トリミングされたランタイム アプリ、トリミングされていないランタイム アプリのパフォーマンスを比較するために、Microsoft のベンチマーク ラボで実行されました。 次のグラフはベンチマークの結果を示しています。
上のグラフから、ネイティブ AOT はアプリ サイズ、メモリ使用量、起動時間が低いことがわかります。
ASP.NET Core とネイティブ AOT の互換性
現在、ASP.NET Core のすべての機能がネイティブ AOT と互換性を持つわけではありません。 次の表は、ASP.NET Core 機能のネイティブ AOT との互換性をまとめたものです。
機能 | 完全にサポート | 部分的にサポートされる | サポートしていません。 |
---|---|---|---|
gRPC | 完全にサポート | ||
最小 Api | 部分的にサポート | ||
MVC | サポートされていません | ||
Blazor Server | サポートされていません | ||
SignalR | 部分的にサポート | ||
JWT 認証 | 完全にサポート | ||
他の認証 | サポートされていません | ||
CORS | 完全にサポート | ||
HealthChecks | 完全にサポート | ||
HttpLogging | 完全にサポート | ||
ローカライズ | 完全にサポート | ||
OutputCaching | 完全にサポート | ||
RateLimiting | 完全にサポート | ||
RequestDecompression | 完全にサポート | ||
ResponseCaching | 完全にサポート | ||
ResponseCompression | 完全にサポート | ||
Rewrite | 完全にサポート | ||
Session | サポートされていません | ||
スパ | サポートされていません | ||
StaticFiles | 完全にサポート | ||
WebSocket | 完全にサポート |
制限事項の詳細については、以下を参照してください:
ネイティブ AOT デプロイ モデルに移行するときには、アプリを徹底的にテストすることが重要です。 AOT デプロイ アプリをテストして、トリミングされていない JIT コンパイル アプリと機能が変わっていないことを確認する必要があります。 アプリをビルドするときに、AOT の警告を確認して修正します。 発行中に AOT 警告 を発行するアプリが正しく機能しない可能性があります。 発行時に AOT 警告が発行されない場合、発行された AOT アプリは、未インストールの JIT コンパイル 済みアプリと同じように動作する必要があります。
ネイティブ AOT の発行
ネイティブ AOT は PublishAot
MSBuild プロパティを使って有効になります。 プロジェクト ファイルでネイティブ AOT を有効にする方法の例を次に示します。
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
この設定により、発行時にネイティブ AOT コンパイルが有効になり、ビルド中と編集中に動的なコード使用状況分析が有効になります。 ネイティブ AOT の発行を使うプロジェクトは、ローカルで実行するときに JIT コンパイルを使います。 AOT アプリと JIT コンパイル アプリには次のような違いがあります。
- ネイティブ AOT と互換性のない機能は無効になり、実行時に例外がスローされます。
- ソース アナライザーが有効になり、ネイティブ AOT と互換性のないコードが強調表示されます。 発行時に、NuGet パッケージを含むアプリ全体の互換性がもう一度分析されます。
ネイティブ AOT の分析には、アプリのすべてのコードと、アプリが依存するライブラリが含まれます。 ネイティブ AOT の警告を確認し、修正手順を実行してください。 開発ライフサイクルの早い段階で問題を検出するために、頻繁にアプリを発行することをお勧めします。
.NET 8 では、ネイティブ AOT は以下の ASP.NET Core アプリの種類でサポートされています。
- 最小 API - 詳細については、この記事で後述する「Web API (ネイティブ AOT) テンプレート」セクションを参照してください。
- gRPC - 詳細については、「gRPC とネイティブ AOT」を参照してください。
- worker サービス - 詳細については、worker サービス テンプレートでの AOT に関する記事を参照してください。
Web API (ネイティブ AOT) テンプレート
ASP.NET Core Web API (ネイティブ AOT) テンプレート (短縮名 webapiaot
) を使用して、AOT が有効なプロジェクトを作成します。 このテンプレートは、Web API プロジェクト テンプレートと次の点で異なります。
- MVC はネイティブ AOT とまだ互換性がないため、最小限の API のみを使います。
- CreateSlimBuilder() API を使って必要な機能のみを既定で有効にし、アプリのデプロイ サイズを最小限に抑えます。
- クラウドネイティブ デプロイでは HTTPS トラフィックはイングレス サービスで処理されるのが一般的なので、HTTP のみをリッスンするように構成されています。
- IIS または IIS Express で実行するための起動プロファイルは含まれません。
- アプリのエンドポイントに送信できる、サンプル HTTP 要求を使って構成された
.http
ファイルを作成します。 - 天気予報のサンプルではなく、サンプル
Todo
API が含まれています。 PublishAot
この記事で前述したように、プロジェクト ファイルに を追加します。- JSON シリアライザー ソース ジェネレーターを有効にします。 ソース ジェネレーターは、ネイティブ AOT コンパイルに必要なシリアル化コードをビルド時に生成するために使われます。
ソース生成をサポートするための変更
次の例は、JSON シリアル化ソース生成をサポートするために Program.cs
ファイルに追加するコードを示しています。
using MyFirstAotWebApi;
+using System.Text.Json.Serialization;
-var builder = WebApplication.CreateBuilder();
+var builder = WebApplication.CreateSlimBuilder(args);
+builder.Services.ConfigureHttpJsonOptions(options =>
+{
+ options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
+});
var app = builder.Build();
var sampleTodos = TodoGenerator.GenerateTodos().ToArray();
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();
+[JsonSerializable(typeof(Todo[]))]
+internal partial class AppJsonSerializerContext : JsonSerializerContext
+{
+
+}
このコードを追加しない場合、System.Text.Json
はリフレクションを使って JSON のシリアル化と逆シリアル化を行います。 リフレクションはネイティブ AOT ではサポートされていません。
詳細については、以下を参照してください:
launchSettings.json
に対する変更
Web API (ネイティブ AOT) テンプレートによって作成された launchSettings.json
ファイルでは、iisSettings
セクションと IIS Express
プロファイルが削除されています。
{
"$schema": "http://json.schemastore.org/launchsettings.json",
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:11152",
- "sslPort": 0
- }
- },
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "todos",
"applicationUrl": "http://localhost:5102",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "launchUrl": "todos",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- }
}
}
CreateSlimBuilder
メソッド
このテンプレートには、CreateBuilder() メソッドではなく CreateSlimBuilder() メソッドが使われています。
using System.Text.Json.Serialization;
using MyFirstAotWebApi;
var builder = WebApplication.CreateSlimBuilder(args);
builder.Logging.AddConsole();
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
var app = builder.Build();
var sampleTodos = TodoGenerator.GenerateTodos().ToArray();
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();
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
CreateSlimBuilder
メソッドを実行すると、アプリを実行するために必要な最小限の ASP.NET Core 機能を使って WebApplicationBuilder が初期化されます。
前述したように、CreateSlimBuilder
メソッドに HTTPS または HTTP/3 のサポートは含まれていません。 通常、これらのプロトコルは、TLS 終端プロキシの背後で実行されるアプリには必要ありません。 たとえば、「Application Gateway での TLS 終端とエンド ツー エンド TLS の概要」を参照してください。 HTTPS を有効にするには、builder.WebHost.UseKestrelHttpsConfiguration を呼び出します。HTTP/3 を有効にするには、builder.WebHost.UseQuic を呼び出します。
CreateSlimBuilder
と CreateBuilder
CreateBuilder
メソッドでサポートされている次の機能は、CreateSlimBuilder
メソッドではサポートされていません。
- ホスティング スタートアップ アセンブリ
- UseStartup
- 次のログ プロバイダー:
- Web ホスト機能:
- Kestrel 構成
- ルーティングで使用される regex および alpha 制約
CreateSlimBuilder
メソッドには、効率的な開発エクスペリエンスに必要な以下の機能が含まれています。
appsettings.json
とappsettings.{EnvironmentName}.json
の JSON ファイルの構成。- ユーザー シークレットの構成。
- コンソールのログ。
- ログの構成。
上述した機能を省略するビルダーについては、CreateEmptyBuilder
メソッドを参照してください。
最小限の機能を備えているので、AOT だけでなくトリミングの点でもベネフィットがあります。 詳細については、「自己完結型の展開と実行可能ファイルのトリミング」を参照してください。
詳細については、「WebApplication.CreateBuilder
と CreateSlimBuilder
を比較する」を参照してください
ソース ジェネレーター
使われないコードはネイティブ AOT の発行中にトリミングされるため、アプリで実行時に無制限のリフレクションを使うことはできません。 ソース ジェネレーターは、リフレクションの必要性を回避するコードを生成するために使われます。 場合によっては、ジェネレーターが必須ではないときでも、ソース ジェネレーターによって AOT 用に最適化されたコードが生成されます。
生成されたソース コードを表示するには、次の例に示すように、アプリの .csproj
ファイルに EmitCompilerGeneratedFiles
プロパティを追加します。
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Other properties omitted for brevity -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
</Project>
dotnet build
コマンドを実行して、生成されたコードを確認します。 出力には、プロジェクトのすべての生成ファイルを含む obj/Debug/net8.0/generated/
ディレクトリが含まれます。
また、dotnet publish
コマンドを実行すると、ソース ファイルがコンパイルされ、コンパイルされたファイルが生成されます。 さらに、dotnet publish
を実行すると、生成されたアセンブリがネイティブ IL コンパイラに渡されます。 IL コンパイラによってネイティブの実行可能ファイルが生成されます。 ネイティブの実行可能ファイルには、ネイティブのマシン コードが含まれています。
ライブラリとネイティブ AOT
現在、ASP.NET Core プロジェクトで使用される一般的なライブラリの多くは、ネイティブ AOT をターゲットとするプロジェクトで使われる場合に次のような互換性の問題があります。
- リフレクションの利用により、型が検査して検出される。
- 実行時にライブラリが条件付きで読み込まれる。
- 機能を実装するためのコードがすぐに生成される。
ネイティブ AOT を使用するには、これらの動的機能を使用するライブラリを更新する必要があります。 Roslyn ソース ジェネレーターなどのツールを使用して更新できます。
ネイティブ AOT のサポートを希望するライブラリ作成者には、次のことをおすすめします。
Minimal API と JSON ペイロード
Minimal API フレームワークは、System.Text.Json を使用して JSON ペイロードを受け取って返すように最適化されています。 System.Text.Json
:
- JSON とネイティブ AOT の互換性要件を設定します。
System.Text.Json
ソース ジェネレーターを使用する必要があります。
最小 API アプリで HTTP 本文の一部として送信される、または要求デリゲートから返されるすべての型は、ASP.NET Core の依存関係の挿入によって登録された JsonSerializerContext で構成する必要があります。
using System.Text.Json.Serialization;
using MyFirstAotWebApi;
var builder = WebApplication.CreateSlimBuilder(args);
builder.Logging.AddConsole();
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
var app = builder.Build();
var sampleTodos = TodoGenerator.GenerateTodos().ToArray();
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();
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
前の強調表示されたコードでは、次のようになっています。
- JSON シリアライザー コンテキストは、DI コンテナーに登録されます。 詳細については、以下をご覧ください。
- カスタム
JsonSerializerContext
には、ToDo
型のソース生成 JSON シリアライザー コードを有効にするために、[JsonSerializable]
属性で注釈が付けられます。
本文にバインドされておらず、シリアル化できるようにする必要の "ない" デリゲート上のパラメーター。 たとえば、リッチ オブジェクト型であり、IParsable<T>
を実装するクエリ文字列パラメーターです。
public class Todo
{
public int Id { get; set; }
public string? Title { get; set; }
public DateOnly? DueBy { get; set; }
public bool IsComplete { get; set; }
}
static class TodoGenerator
{
private static readonly (string[] Prefixes, string[] Suffixes)[] _parts = new[]
{
(new[] { "Walk the", "Feed the" }, new[] { "dog", "cat", "goat" }),
(new[] { "Do the", "Put away the" }, new[] { "groceries", "dishes", "laundry" }),
(new[] { "Clean the" }, new[] { "bathroom", "pool", "blinds", "car" })
};
// Remaining code omitted for brevity.
既知の問題
ASP.NET Core のネイティブ AOT サポートに関する問題の報告またはレビューについては、この GitHub issue を参照してください。
関連項目
ASP.NET Core 8.0 では、.NET ネイティブ Ahead-Of-Time (AOT) のサポートが導入されています。
ASP.NET Core でネイティブ AOT を使う理由
ネイティブ AOT アプリを発行およびデプロイすることには、次の利点があります。
- ディスク占有領域を最小限に抑える: ネイティブ AOT を使って発行すると、プログラムをサポートするために必要な外部依存関係のコードのみを含む 1 つの実行可能ファイルが生成されます。 実行可能ファイルのサイズ削減は、次につながります。
- より小さいコンテナー イメージ (たとえば、コンテナー化されたデプロイのシナリオで)。
- より小さいイメージからデプロイ時間を短縮する。
- 起動時間の短縮: ネイティブ AOT アプリケーションでは、起動時間が短縮される可能性があります。つまり、次のことが言えます。
- より迅速にアプリが要求を処理する準備が整う。
- アプリのあるバージョンから別のバージョンへの移行をコンテナー オーケストレーターで管理する必要がある場合、デプロイが改善される。
- 必要なメモリの削減: ネイティブ AOT アプリでは、アプリによって実行される作業に応じて、必要なメモリを減らすことができます。 メモリ消費量が減ると、デプロイの密度が高くなり、スケーラビリティが向上する可能性があります。
テンプレート アプリは、AOT 公開アプリ、トリミングされたランタイム アプリ、トリミングされていないランタイム アプリのパフォーマンスを比較するために、Microsoft のベンチマーク ラボで実行されました。 次のグラフはベンチマークの結果を示しています。
上のグラフから、ネイティブ AOT はアプリ サイズ、メモリ使用量、起動時間が低いことがわかります。
ASP.NET Core とネイティブ AOT の互換性
現在、ASP.NET Core のすべての機能がネイティブ AOT と互換性を持つわけではありません。 次の表は、ASP.NET Core 機能のネイティブ AOT との互換性をまとめたものです。
機能 | 完全にサポート | 部分的にサポートされる | サポートしていません。 |
---|---|---|---|
gRPC | 完全にサポート | ||
最小 Api | 部分的にサポート | ||
MVC | サポートされていません | ||
Blazor Server | サポートされていません | ||
SignalR | サポートされていません | ||
JWT 認証 | 完全にサポート | ||
他の認証 | サポートされていません | ||
CORS | 完全にサポート | ||
HealthChecks | 完全にサポート | ||
HttpLogging | 完全にサポート | ||
ローカライズ | 完全にサポート | ||
OutputCaching | 完全にサポート | ||
RateLimiting | 完全にサポート | ||
RequestDecompression | 完全にサポート | ||
ResponseCaching | 完全にサポート | ||
ResponseCompression | 完全にサポート | ||
Rewrite | 完全にサポート | ||
Session | サポートされていません | ||
スパ | サポートされていません | ||
StaticFiles | 完全にサポート | ||
WebSocket | 完全にサポート |
制限事項の詳細については、以下を参照してください:
ネイティブ AOT デプロイ モデルに移行するときには、アプリを徹底的にテストすることが重要です。 AOT デプロイ アプリをテストして、トリミングされていない JIT コンパイル アプリと機能が変わっていないことを確認する必要があります。 アプリをビルドするときに、AOT の警告を確認して修正します。 発行中に AOT 警告 を発行するアプリが正しく機能しない可能性があります。 発行時に AOT 警告が発行されない場合、発行された AOT アプリは、未インストールの JIT コンパイル 済みアプリと同じように動作する必要があります。
ネイティブ AOT の発行
ネイティブ AOT は PublishAot
MSBuild プロパティを使って有効になります。 プロジェクト ファイルでネイティブ AOT を有効にする方法の例を次に示します。
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
この設定により、発行時にネイティブ AOT コンパイルが有効になり、ビルド中と編集中に動的なコード使用状況分析が有効になります。 ネイティブ AOT の発行を使うプロジェクトは、ローカルで実行するときに JIT コンパイルを使います。 AOT アプリと JIT コンパイル アプリには次のような違いがあります。
- ネイティブ AOT と互換性のない機能は無効になり、実行時に例外がスローされます。
- ソース アナライザーが有効になり、ネイティブ AOT と互換性のないコードが強調表示されます。 発行時に、NuGet パッケージを含むアプリ全体の互換性がもう一度分析されます。
ネイティブ AOT の分析には、アプリのすべてのコードと、アプリが依存するライブラリが含まれます。 ネイティブ AOT の警告を確認し、修正手順を実行してください。 開発ライフサイクルの早い段階で問題を検出するために、頻繁にアプリを発行することをお勧めします。
.NET 8 では、ネイティブ AOT は以下の ASP.NET Core アプリの種類でサポートされています。
- 最小 API - 詳細については、この記事で後述する「Web API (ネイティブ AOT) テンプレート」セクションを参照してください。
- gRPC - 詳細については、「gRPC とネイティブ AOT」を参照してください。
- worker サービス - 詳細については、worker サービス テンプレートでの AOT に関する記事を参照してください。
Web API (ネイティブ AOT) テンプレート
ASP.NET Core Web API (ネイティブ AOT) テンプレート (短縮名 webapiaot
) を使用して、AOT が有効なプロジェクトを作成します。 このテンプレートは、Web API プロジェクト テンプレートと次の点で異なります。
- MVC はネイティブ AOT とまだ互換性がないため、最小限の API のみを使います。
- CreateSlimBuilder() API を使って必要な機能のみを既定で有効にし、アプリのデプロイ サイズを最小限に抑えます。
- クラウドネイティブ デプロイでは HTTPS トラフィックはイングレス サービスで処理されるのが一般的なので、HTTP のみをリッスンするように構成されています。
- IIS または IIS Express で実行するための起動プロファイルは含まれません。
- アプリのエンドポイントに送信できる、サンプル HTTP 要求を使って構成された
.http
ファイルを作成します。 - 天気予報のサンプルではなく、サンプル
Todo
API が含まれています。 PublishAot
この記事で前述したように、プロジェクト ファイルに を追加します。- JSON シリアライザー ソース ジェネレーターを有効にします。 ソース ジェネレーターは、ネイティブ AOT コンパイルに必要なシリアル化コードをビルド時に生成するために使われます。
ソース生成をサポートするための変更
次の例は、JSON シリアル化ソース生成をサポートするために Program.cs
ファイルに追加するコードを示しています。
using MyFirstAotWebApi;
+using System.Text.Json.Serialization;
-var builder = WebApplication.CreateBuilder();
+var builder = WebApplication.CreateSlimBuilder(args);
+builder.Services.ConfigureHttpJsonOptions(options =>
+{
+ options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
+});
var app = builder.Build();
var sampleTodos = TodoGenerator.GenerateTodos().ToArray();
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();
+[JsonSerializable(typeof(Todo[]))]
+internal partial class AppJsonSerializerContext : JsonSerializerContext
+{
+
+}
このコードを追加しない場合、System.Text.Json
はリフレクションを使って JSON のシリアル化と逆シリアル化を行います。 リフレクションはネイティブ AOT ではサポートされていません。
詳細については、以下を参照してください:
launchSettings.json
に対する変更
Web API (ネイティブ AOT) テンプレートによって作成された launchSettings.json
ファイルでは、iisSettings
セクションと IIS Express
プロファイルが削除されています。
{
"$schema": "http://json.schemastore.org/launchsettings.json",
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:11152",
- "sslPort": 0
- }
- },
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "todos",
"applicationUrl": "http://localhost:5102",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "launchUrl": "todos",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- }
}
}
CreateSlimBuilder
メソッド
このテンプレートには、CreateBuilder() メソッドではなく CreateSlimBuilder() メソッドが使われています。
using System.Text.Json.Serialization;
using MyFirstAotWebApi;
var builder = WebApplication.CreateSlimBuilder(args);
builder.Logging.AddConsole();
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
var app = builder.Build();
var sampleTodos = TodoGenerator.GenerateTodos().ToArray();
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();
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
CreateSlimBuilder
メソッドを実行すると、アプリを実行するために必要な最小限の ASP.NET Core 機能を使って WebApplicationBuilder が初期化されます。
前述したように、CreateSlimBuilder
メソッドに HTTPS または HTTP/3 のサポートは含まれていません。 通常、これらのプロトコルは、TLS 終端プロキシの背後で実行されるアプリには必要ありません。 たとえば、「Application Gateway での TLS 終端とエンド ツー エンド TLS の概要」を参照してください。 HTTPS を有効にするには、builder.WebHost.UseKestrelHttpsConfiguration を呼び出します。HTTP/3 を有効にするには、builder.WebHost.UseQuic を呼び出します。
CreateSlimBuilder
と CreateBuilder
CreateBuilder
メソッドでサポートされている次の機能は、CreateSlimBuilder
メソッドではサポートされていません。
- ホスティング スタートアップ アセンブリ
- UseStartup
- 次のログ プロバイダー:
- Web ホスト機能:
- Kestrel 構成
- ルーティングで使用される regex および alpha 制約
CreateSlimBuilder
メソッドには、効率的な開発エクスペリエンスに必要な以下の機能が含まれています。
appsettings.json
とappsettings.{EnvironmentName}.json
の JSON ファイルの構成。- ユーザー シークレットの構成。
- コンソールのログ。
- ログの構成。
上述した機能を省略するビルダーについては、CreateEmptyBuilder
メソッドを参照してください。
最小限の機能を備えているので、AOT だけでなくトリミングの点でもベネフィットがあります。 詳細については、「自己完結型の展開と実行可能ファイルのトリミング」を参照してください。
詳細については、「WebApplication.CreateBuilder
と CreateSlimBuilder
を比較する」を参照してください
ソース ジェネレーター
使われないコードはネイティブ AOT の発行中にトリミングされるため、アプリで実行時に無制限のリフレクションを使うことはできません。 ソース ジェネレーターは、リフレクションの必要性を回避するコードを生成するために使われます。 場合によっては、ジェネレーターが必須ではないときでも、ソース ジェネレーターによって AOT 用に最適化されたコードが生成されます。
生成されたソース コードを表示するには、次の例に示すように、アプリの .csproj
ファイルに EmitCompilerGeneratedFiles
プロパティを追加します。
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Other properties omitted for brevity -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
</Project>
dotnet build
コマンドを実行して、生成されたコードを確認します。 出力には、プロジェクトのすべての生成ファイルを含む obj/Debug/net8.0/generated/
ディレクトリが含まれます。
また、dotnet publish
コマンドを実行すると、ソース ファイルがコンパイルされ、コンパイルされたファイルが生成されます。 さらに、dotnet publish
を実行すると、生成されたアセンブリがネイティブ IL コンパイラに渡されます。 IL コンパイラによってネイティブの実行可能ファイルが生成されます。 ネイティブの実行可能ファイルには、ネイティブのマシン コードが含まれています。
ライブラリとネイティブ AOT
現在、ASP.NET Core プロジェクトで使用される一般的なライブラリの多くは、ネイティブ AOT をターゲットとするプロジェクトで使われる場合に次のような互換性の問題があります。
- リフレクションの利用により、型が検査して検出される。
- 実行時にライブラリが条件付きで読み込まれる。
- 機能を実装するためのコードがすぐに生成される。
ネイティブ AOT を使用するには、これらの動的機能を使用するライブラリを更新する必要があります。 Roslyn ソース ジェネレーターなどのツールを使用して更新できます。
ネイティブ AOT のサポートを希望するライブラリ作成者には、次のことをおすすめします。
Minimal API と JSON ペイロード
Minimal API フレームワークは、System.Text.Json を使用して JSON ペイロードを受け取って返すように最適化されています。 System.Text.Json
:
- JSON とネイティブ AOT の互換性要件を設定します。
System.Text.Json
ソース ジェネレーターを使用する必要があります。
最小 API アプリで HTTP 本文の一部として送信される、または要求デリゲートから返されるすべての型は、ASP.NET Core の依存関係の挿入によって登録された JsonSerializerContext で構成する必要があります。
using System.Text.Json.Serialization;
using MyFirstAotWebApi;
var builder = WebApplication.CreateSlimBuilder(args);
builder.Logging.AddConsole();
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
var app = builder.Build();
var sampleTodos = TodoGenerator.GenerateTodos().ToArray();
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();
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
前の強調表示されたコードでは、次のようになっています。
- JSON シリアライザー コンテキストは、DI コンテナーに登録されます。 詳細については、以下をご覧ください。
- カスタム
JsonSerializerContext
には、ToDo
型のソース生成 JSON シリアライザー コードを有効にするために、[JsonSerializable]
属性で注釈が付けられます。
本文にバインドされておらず、シリアル化できるようにする必要の "ない" デリゲート上のパラメーター。 たとえば、リッチ オブジェクト型であり、IParsable<T>
を実装するクエリ文字列パラメーターです。
public class Todo
{
public int Id { get; set; }
public string? Title { get; set; }
public DateOnly? DueBy { get; set; }
public bool IsComplete { get; set; }
}
static class TodoGenerator
{
private static readonly (string[] Prefixes, string[] Suffixes)[] _parts = new[]
{
(new[] { "Walk the", "Feed the" }, new[] { "dog", "cat", "goat" }),
(new[] { "Do the", "Put away the" }, new[] { "groceries", "dishes", "laundry" }),
(new[] { "Clean the" }, new[] { "bathroom", "pool", "blinds", "car" })
};
// Remaining code omitted for brevity.
既知の問題
ASP.NET Core のネイティブ AOT サポートに関する問題の報告またはレビューについては、この GitHub issue を参照してください。
関連項目
ASP.NET Core