Mitch Dennyによる
ASP.NET Coreでのネイティブ 事前割り当て (AOT) アプリケーションの発行とデプロイには、いくつかの利点があります。
ディスク占有領域を最小限に抑えました。 ネイティブ AOT を使用してアプリを発行すると、プロセスによって 1 つの実行可能ファイルが生成されます。 実行可能ファイルには、アプリをサポートするために必要な外部依存関係のコードのみが含まれています。 実行可能ファイルのサイズが小さいと、次の結果が生じる可能性があります。
- より小さいコンテナー イメージ (たとえば、コンテナー化されたデプロイのシナリオで)。
- より小さいイメージからデプロイ時間を短縮する。
起動時間が短縮されました。 ネイティブ AOT アプリの起動時間を短縮できるため、次のことが可能になります。
- リクエストをより迅速にサービスするためのアプリ。
- コンテナー オーケストレーターがアプリ バージョン間の移行を管理するデプロイが改善されました。
メモリ需要の削減。 ネイティブ AOT アプリでは、アプリによって実行される作業に応じて、必要なメモリが少なくなる場合があります。 メモリ消費量が減ると、デプロイの密度が高くなり、スケーラビリティが向上する可能性があります。
次のグラフは、さまざまなテンプレート アプリでのベンチマーク テストの結果を示しています。 このベンチマークでは、AOT 公開アプリ (オレンジ色のバー)、トリミングされたランタイム アプリ (緑のバー)、およびトリミングされていないランタイム アプリ (黄色のバー) のパフォーマンスが比較されます。 このテストでは、ネイティブ AOT アプリのアプリ サイズ、メモリ使用量、および起動時間が小さいことが明らかになります。
この記事では、発行とデプロイの概要など、ASP.NET Coreでのネイティブ AOT アプリのサポートについて説明します。
この記事のガイダンスに追加または置き換えられる ASP.NET Core Blazor WebAssembly Native AOT ガイダンスについては、ASP.NET Core Blazor WebAssembly ビルド ツールと事前 (AOT) コンパイルを参照してください。
ASP.NET Coreとネイティブ AOT の互換性を確認する
現在、ASP.NET Core のすべての機能がネイティブ AOT と互換性を持つわけではありません。
次の表は、ASP.NET Core 機能のネイティブ AOT との互換性をまとめたものです。
| 機能 | Supported | 部分的なサポート | サポートしていません |
|---|---|---|---|
| Blazor Server | ❌ | ||
| CORS | ✔️ | ||
| gRPC | ✔️ | ||
| HealthChecks | ✔️ | ||
| HTTP ロギング | ✔️ | ||
| JWT 認証 | ✔️ | ||
| ローカライズ | ✔️ | ||
| ミニマル API | ✔️ | ||
| MVC | ❌ | ||
| 他の認証 | ❌ | ||
| 出力キャッシュ | ✔️ | ||
| レート制限 | ✔️ | ||
| リクエスト解凍 | ✔️ | ||
| ResponseCaching | ✔️ | ||
| レスポンス圧縮 | ✔️ | ||
| 書き直す | ✔️ | ||
| セッション | ❌ | ||
| SignalR | ✔️ | ||
| スパ | ❌ | ||
| StaticFiles | ✔️ | ||
| WebSocket | ✔️ |
制限事項の詳細については、以下を参照してください:
ネイティブ AOT デプロイ モデルでアプリを確認する
ネイティブ AOT デプロイ モデルに移行するときは、アプリを徹底的にテストすることが重要です。 AOT でデプロイされたアプリをテストし、機能が未検証の Just-In-Time (JIT) コンパイル 済みアプリから変更されていないことを確認します。
アプリをビルドするときは、AOT の警告を確認して修正します。 発行中に AOT 警告 を発行するアプリが正しく機能しない可能性があります。 発行時に AOT 警告が発行されない場合は、発行された AOT アプリが、未インストールの JIT コンパイル 済みアプリと同じように動作することが期待できます。
ネイティブ AOT アプリを発行する (PublishAot)
PublishAot MSBuild プロパティを使用して、アプリケーションのネイティブ AOT を有効にします。 プロジェクト ファイルでネイティブ AOT を有効にする方法の例を次に示します。
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
PublishAot プロパティを使用すると、発行プロセス中にネイティブ AOT コンパイルが有効になり、ビルドと編集中に動的なコード使用状況分析が可能になります。 ネイティブ AOT 発行を使用するプロジェクトは、ローカルで実行されるときに JIT コンパイルを実装します。
AOT アプリと JIT コンパイル アプリには次のような違いがあります。
- ネイティブ AOT と互換性のない機能は無効化され、実行時に例外が発生します。
- ソース アナライザーが有効になり、ネイティブ AOT と互換性のないコードが強調表示されます。 発行時に、NuGet パッケージを含むアプリ全体の互換性がもう一度分析されます。
ネイティブ AOT 分析には、すべてのアプリケーション コードと、アプリが依存するライブラリが含まれます。 ネイティブ AOT の警告を確認し、修正手順を実行してください。 開発ライフサイクルの早い段階で問題を検出するために、頻繁にアプリを発行することをお勧めします。
.NET 8 以降では、次の ASP.NET Coreアプリの種類がネイティブ AOT をサポートしています。
- 最小限の API - 詳細については、この記事の後半の 「Web API (ネイティブ AOT) テンプレートを確認 する」を参照してください。
- gRPC - 詳細については、 gRPC とネイティブ AOT を参照してください。
- Worker services - 詳細については、ASP.NET Core Native AOT におけるホストされたサービスのバックグラウンド タスク> を参照してください。
Web API (ネイティブ AOT) テンプレートを確認する
ASP.NET Core Web API (ネイティブ AOT) テンプレート (短い名前 webapiaot) は、AOT が有効になっているプロジェクトを作成します。 このテンプレートは、次の点で標準 の Web API プロジェクト テンプレートとは異なります。
- MVC はまだネイティブ AOT と互換性がないので、最小限の API のみを使用します。
- CreateSlimBuilder() API を使用して、基本的な機能のみが既定で有効になっていることを確認します。これにより、アプリのデプロイされたサイズが最小限に抑えられます。
- HTTP でのみリッスンするように構成されています。 HTTPS トラフィックは、一般的にクラウドネイティブ デプロイのイングレス サービスによって処理されます。
- IIS または IIS Express で実行するための起動プロファイルは含まれません。
- アプリのエンドポイントに送信できるサンプル HTTP 要求で構成された .http ファイル を作成します。
- 天気予報のサンプルではなく、サンプル
TodoAPI が含まれています。 - 前に説明したように、
PublishAotプロパティをプロジェクト ファイルに追加 します。 - JSON シリアライザー ソース ジェネレーターを有効にします。 ソース ジェネレーターは、ネイティブ AOT コンパイルに必要なシリアル化コードをビルド時に生成するために使われます。
JSON シリアル化のコード更新 (Program.cs)
Program.cs ファイル内のコードは、JSON シリアル化ソースの生成をサポートするように変更されます。
次のスニペットは、コードの変更を示しています。
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() が最小限のアプリの既定値のために呼び出されました。
Web API (ネイティブ AOT) テンプレートでは、CreateSlimBuilder() メソッドの代わりに CreateBuilder() メソッドが使用されます。
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 を有効にすることができます 。WebHost.UseKestrelHttpsConfiguration メソッド、またはビルダーを呼び出して HTTP/3 を有効にします 。WebHost.UseQuic。
CreateSlimBuilder() と CreateBuilder() を比較する
CreateSlimBuilder メソッドを使用すると、CreateBuilder メソッドで使用できるアプリケーション機能の一部にアクセスできます。 前述のように、Web API (Native AOT) テンプレートは CreateSlimBuilder を呼び出して WebApplicationBuilder を初期化するため、ビルダーはアプリの実行に必要な最小限の ASP.NET Core機能を使用します。
どちらの方法でも、効率的な開発エクスペリエンスに必要な機能が提供されます。
- appsettings.json と appsettings.{EnvironmentName}.json ファイルの構成
- ユーザー シークレットの構成
- コンソールのログ記録
- ログ記録の構成
最小限の機能を備えているので、AOT だけでなくトリミングの点でもベネフィットがあります。 詳細については、「自己完結型の展開と実行可能ファイルのトリミング」を参照してください。
すべての機能を省略するビルダーを使用する場合は、 WebApplication.CreateEmptyBuilder メソッドを参照してください。
CreateSlimBuilder で使用できない機能
CreateSlimBuilder メソッドには、で使用できる次の機能は用意CreateBuilder。
- スタートアップ 会合のホスティング
- UseStartup メソッド
- ログ記録プロバイダー
- Web ホスト機能:
- Kestrel 構成:
- ルーティングで使用されるregex制約とアルファ制約 (GitHub /dotnet/aspnetcore/issues #46142)
詳細については、「WebApplication.CreateBuilder と CreateSlimBuilder の比較」を参照してください。
ソース ジェネレーターを使用してリフレクションを回避する
ネイティブ AOT の発行プロセス中に、未使用のコードはすべてトリミングされます。 その結果、アプリは実行時に無制限のリフレクションを使用できません。 リフレクションの必要を回避するコードを生成する ソース ジェネレーター を使用できます。 場合によっては、ジェネレーターが必要ない場合でも、AOT 用に最適化されたソース ジェネレーターの出力コード。
生成されたソース コードを表示するには、 EmitCompilerGeneratedFiles プロパティをアプリケーション プロジェクト (.csproj) ファイルに追加します。
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <!-- Other properties omitted for brevity --> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> </PropertyGroup> </Project>生成されたコードを表示するには、
dotnet buildコマンドを実行します。 このコマンドは、ソース ファイルをコンパイルし、開発環境でアプリを実行するために必要な中間ファイルを生成します。 出力には、プロジェクトに関連するすべての生成ファイルを含むobj/Debug/<.NET バージョン>/generated/ ディレクトリが含まれます。アプリをデプロイ用に準備するには、
dotnet publishコマンドを実行します。 このコマンドは、ソース ファイルをコンパイルし、アプリのデプロイに必要なすべてのファイルを生成します。 生成されたアセンブリがネイティブ IL コンパイラに渡され、ネイティブ実行可能ファイルが生成されます。 ネイティブの実行可能ファイルには、ネイティブのマシン コードが含まれています。
ネイティブ AOT でライブラリを使用する
ASP.NET Core プロジェクトで使用される多くの一般的なライブラリには、現在、ネイティブ AOT を対象とするプロジェクトに組み込まれている場合、次のような互換性の問題があります。
- リフレクションを使用して型を検査し、発見すること
- 実行時に条件付きでライブラリを読み込む
- 機能を実装するためのコードをすぐに生成する
これらの動的機能を使用するライブラリでは、ネイティブ AOT を使用するための更新が必要です。 Roslyn ソース ジェネレーターなど、必要な更新プログラムを適用するために、さまざまなツールを使用できます。
Native AOT をサポートすることを希望するライブラリ作成者は、次の記事を確認することをお勧めします。
最小限の API と JSON ペイロードの操作
最小 API フレームワークは、 System.Text.Jsonを使用して JSON ペイロードを受信および返すように最適化されています。
- この名前空間では、JSON とネイティブ AOT の互換性要件が課されます。
- これには、System.Text.Json ソース ジェネレーターを使用する必要があります。
HTTP 本文の一部として送信されるか、Minimal API アプリの要求デリゲートから返されるすべての型は、 JsonSerializerContext インスタンスで構成する必要があります。 ASP.NET Coreの依存関係注入にインスタンスを登録する必要があります。
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 コンテナーに登録されます。 詳細については、「TypeInfoResolverChain」を参照してください。
カスタム
JsonSerializerContextには JsonSerializable 属性で注釈が付けられます。これにより、ToDo型のソース生成 JSON シリアライザー コードが有効になります。
本文にバインドされていないデリゲートのパラメーターをシリアル化できる必要 はありません 。 たとえば、クエリ文字列パラメーターには、 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 /dotnet/core/issues #8288)を参照してください。
関連するコンテンツ
ネイティブ AOT - ネイティブ AOT 展開
- AOT デプロイを最適化する
.NET 8 では、 .NET ネイティブの事前準備 (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 | 完全にサポート | ||
| HTTP ロギング | 完全にサポート | ||
| ローカライズ | 完全にサポート | ||
| 出力キャッシュ | 完全にサポート | ||
| レート制限 | 完全にサポート | ||
| リクエスト解凍 | 完全にサポート | ||
| ResponseCaching | 完全にサポート | ||
| レスポンス圧縮 | 完全にサポート | ||
| 書き直す | 完全にサポート | ||
| セッション | サポートされていません | ||
| スパ | サポートされていません | ||
| 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ファイルを作成します。 - 天気予報のサンプルではなく、サンプル
TodoAPI が含まれています。 -
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 に対する変更
launchSettings.json Web API (Native AOT) テンプレートによって作成された ファイルでは、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 メソッド
このテンプレートには、CreateSlimBuilder() メソッドではなく CreateBuilder() メソッドが使われています。
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 を有効にするには、ビルダーを呼び出します。WebHost.UseKestrelHttpsConfiguration HTTP/3 は、ビルダーを呼び出すことによって有効にすることができます。WebHost.UseQuic.
CreateSlimBuilder と CreateBuilder
CreateSlimBuilder メソッドでサポートされている次の機能は、CreateBuilder メソッドではサポートされていません。
- スタートアップ 会合のホスティング
- UseStartup
- 次のログ プロバイダー:
- Web ホスト機能:
- Kestrel 構成
- ルーティングで使用される regex および alpha 制約
CreateSlimBuilder メソッドには、効率的な開発エクスペリエンスに必要な以下の機能が含まれています。
-
appsettings.jsonとappsettings.{EnvironmentName}.jsonの JSON ファイルの構成。 - ユーザー シークレットの構成。
- コンソールでのログ記録。
- ログ設定。
上述した機能を省略するビルダーについては、CreateEmptyBuilder メソッドを参照してください。
最小限の機能を備えているので、AOT だけでなくトリミングの点でもベネフィットがあります。 詳細については、「自己完結型の展開と実行可能ファイルのトリミング」を参照してください。
詳細については、「WebApplication.CreateBuilder と CreateSlimBuilder を比較する」を参照してください
ソース ジェネレーター
使われないコードはネイティブ AOT の発行中にトリミングされるため、アプリで実行時に無制限のリフレクションを使うことはできません。 ソース ジェネレーターは、リフレクションの必要性を回避するコードを生成するために使われます。 場合によっては、ジェネレーターが必須ではないときでも、ソース ジェネレーターによって AOT 用に最適化されたコードが生成されます。
生成されたソース コードを表示するには、次の例に示すように、アプリの EmitCompilerGeneratedFiles ファイルに .csproj プロパティを追加します。
<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 ソース ジェネレーターなど、必要な更新プログラムを適用するために、さまざまなツールを使用できます。
Native AOT をサポートすることを希望するライブラリ作成者は、次の記事を確認することをお勧めします。
ミニマル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には、[JsonSerializable]型のソース生成 JSON シリアライザー コードを有効にするために、ToDo属性で注釈が付けられます。
デリゲート上のパラメーターで、本文にバインドされておらず、シリアル化可能である必要のないもの。 たとえば、リッチ オブジェクト型であり、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