ASP.NET Core-Unterstützung für native AOT-Kompilierung
Von Mitch Denny
In ASP.NET Core 8.0 wird Unterstützung für native .NET-AOT-Kompilierung (Ahead-Of-Time) eingeführt.
Anleitungen zu nativer AOT-Kompilierung in Blazor WebAssembly, die Anleitungen in diesem Artikel ergänzen oder ersetzen, finden Sie unter Build-Tools und AOT-Kompilierung (ahead-of-time) in ASP.NET Core-Blazor WebAssembly .
Gründe für die Verwendung von nativer AOT-Kompilierung mit ASP.NET Core
Das Veröffentlichen und Bereitstellen einer nativen AOT-App bietet die folgenden Vorteile:
- Minimierter benötigter Speicherplatz auf dem Datenträger: Bei der Veröffentlichung mit nativer AOT-Kompilierung wird eine einzelne ausführbare Datei erstellt, die nur den Code aus externen Abhängigkeiten enthält, der zur Unterstützung des Programms erforderlich ist. Die reduzierte Größe ausführbarer Dateien kann zu Folgendem führen:
- Kleinere Containerimages, z. B. in Containerbereitstellungsszenarien
- Kürzere Bereitstellungsdauer durch kleinere Images
- Verkürzte Startzeit: Native AOT-Anwendungen können kürzere Startzeiten aufweisen. Dies bedeutet
- Die App kann Anforderungen schneller verarbeiten.
- Verbesserte Bereitstellung, bei der Containerorchestratoren den Übergang von einer Version der App zu einer anderen verwalten müssen
- Reduzierter Speicherbedarf: Native AOT-Apps können je nach den von der App ausgeführten Aktionen einen geringeren Speicherbedarf aufweisen. Eine reduzierte Arbeitsspeichernutzung kann zu einer höheren Bereitstellungsdichte und besserer Skalierbarkeit führen.
Die Vorlagen-App wurde in unserem Benchmark-Lab ausgeführt, um die Leistung einer mit AOT-Kompilierung veröffentlichten App, einer gekürzten Runtime-App und einer nicht gekürzten Runtime-App zu vergleichen. Die folgende Abbildung zeigt die Ergebnisse des Benchmarkings:
Die Abbildung oben zeigt, dass native AOT-Kompilierung eine geringere App-Größe, Arbeitsspeicherauslastung und Startzeit aufweist.
Kompatibilität von ASP.NET Core und nativer AOT-Kompilierung
Nicht alle Features in ASP.NET Core sind derzeit mit nativer AOT-Kompilierung kompatibel. In der folgenden Tabelle ist die Kompatibilität von ASP.NET Core-Features mit nativer AOT-Kompilierung zusammengefasst:
Funktion | Vollständig unterstützt | Teilweise unterstützt | Nicht unterstützt |
---|---|---|---|
gRPC | Vollständig unterstützt | ||
Minimale APIs | Teilweise unterstützt | ||
MVC | Nicht unterstützt | ||
Blazor Server | Nicht unterstützt | ||
SignalR | Teilweise unterstützt | ||
JWT-Authentifizierung | Vollständig unterstützt | ||
Andere Authentifizierung | Nicht unterstützt | ||
CORS | Vollständig unterstützt | ||
HealthChecks | Vollständig unterstützt | ||
HttpLogging | Vollständig unterstützt | ||
Lokalisierung | Vollständig unterstützt | ||
OutputCaching | Vollständig unterstützt | ||
RateLimiting | Vollständig unterstützt | ||
RequestDecompression | Vollständig unterstützt | ||
ResponseCaching | Vollständig unterstützt | ||
ResponseCompression | Vollständig unterstützt | ||
Rewrite | Vollständig unterstützt | ||
Sitzung | Nicht unterstützt | ||
Spa | Nicht unterstützt | ||
StaticFiles | Vollständig unterstützt | ||
WebSockets | Vollständig unterstützt |
Weitere Informationen zu Beschränkungen finden Sie unter:
- Einschränkungen einer nativen AOT-Bereitstellung
- Einführung in AOT-Warnungen
- Bekannte Kürzungsinkompatibilitäten
- Einführung in Kürzungswarnungen
- GitHub issue dotnet/core #8288
Es ist wichtig, eine App gründlich zu testen, wenn Sie zu einem nativen AOT-Bereitstellungsmodell wechseln. Die über die AOT bereitgestellte App sollte getestet werden, um sicherzustellen, dass sich die Funktionalität im Vergleich zur nicht gekürzten und mit JIT kompilierten App nicht geändert hat. Überprüfen und korrigieren Sie AOT-Warnungen beim Erstellen der App. Eine App, die während der Veröffentlichung AOT-Warnungen erzeugt, funktioniert möglicherweise nicht ordnungsgemäß. Wenn zur Veröffentlichungszeit keine AOT-Warnungen ausgegeben werden, sollte die veröffentlichte AOT-App genauso funktionieren wie die ungetrimmte und JIT-kompilierte App.
Native AOT-Veröffentlichung
Native AOT-Kompilierung wird mit der MSBuild-Eigenschaft PublishAot
aktiviert. Das folgende Beispiel zeigt, wie systemeigene AOT-Kompilierung in einer Projektdatei aktiviert wird:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
Diese Einstellung aktiviert native AOT-Kompilierung während der Veröffentlichung und dynamische Analyse der Codeverwendung während des Build- und Bearbeitungsvorgangs. Ein Projekt, das die native AOT-Veröffentlichung verwendet, nutzt bei lokaler Ausführung die JIT-Kompilierung. Eine AOT-App weist die folgenden Unterschiede zu einer JIT-kompilierten App auf:
- Nicht mit nativer AOT-Kompilierung kompatible Features sind deaktiviert und lösen zur Laufzeit Ausnahmen aus.
- Ein Quellanalysetool ist aktiviert, um Code hervorzuheben, der nicht mit nativer AOT-Kompilierung kompatibel ist. Zum Zeitpunkt der Veröffentlichung wird die gesamte App, einschließlich NuGet-Paketen, erneut auf Kompatibilität analysiert.
Die Analyse der nativen AOT-Kompilierung umfasst den gesamten Code der App und die Bibliotheken, von der die App abhängig ist. Überprüfen Sie Warnungen der nativen AOT-Kompilierung und führen Sie Korrekturschritte durch. Es ist ratsam, Apps häufig zu veröffentlichen, um Probleme frühzeitig im Entwicklungslebenszyklus zu erkennen.
In .NET 8 wird native AOT-Kompilierung von den folgenden ASP.NET Core-App-Typen unterstützt:
- Minimale APIs – Weitere Informationen finden Sie weiter unten in diesem Artikel im Abschnitt Web-API-Vorlage (native AOT-Kompilierung).
- gRPC: Weitere Informationen finden Sie unter gRPC und native AOT-Kompilierung.
- Workerdienste: Weitere Informationen finden Sie unter AOT in Worker Service-Vorlagen.
Web-API-Vorlage (native AOT-Kompilierung)
Die ASP.NET Core-Web-API-Vorlage (native AOT-Kompilierung) (Kurzname webapiaot
) erstellt ein Projekt mit aktivierter AOT-Kompilierung. Die Vorlage unterscheidet sich wie folgt von der Web-API-Projektvorlage:
- Verwendet nur minimale APIs, da MVC noch nicht mit nativer AOT-Kompilierung kompatibel ist.
- Verwendet die CreateSlimBuilder()-API, um sicherzustellen, dass nur die wesentlichen Features standardmäßig aktiviert sind, wodurch die bereitgestellte Größe der App minimiert wird.
- Ist so konfiguriert, dass nur auf HTTP gelauscht wird, weil HTTPS-Datenverkehr in cloudnativen Bereitstellungen häufig von einem Eingangsdienst verarbeitet wird.
- Enthält kein Startprofil für die Ausführung unter IIS oder IIS Express.
- Erstellt eine
.http
-Datei, die mit HTTP-Beispielanforderungen konfiguriert ist, die an die Endpunkte der App gesendet werden können. - Enthält eine Beispiel-
Todo
-API anstelle des Beispiels für die Wettervorhersage. - Fügt
PublishAot
zur Projektdatei hinzu, wie weiter oben in diesem Artikel gezeigt. - Aktiviert die JSON-Serialisierer-Quellgeneratoren. Der Quellgenerator wird verwendet, um Serialisierungscode zur Buildzeit zu generieren. Dies ist für native AOT-Kompilierung erforderlich.
Änderungen zur Unterstützung von Quellgenerierung
Das folgende Beispiel zeigt den Code, welcher der Program.cs
-Datei hinzugefügt wurde, um die Generierung von JSON-Serialisierungsquellen zu unterstützen:
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
+{
+
+}
Ohne diesen zusätzlichen Code verwendet System.Text.Json
Reflexion zum Serialisieren und Deserialisieren von JSON. Reflexion wird in nativer AOT-Kompilierung nicht unterstützt.
Weitere Informationen finden Sie unter:
- Kombinieren von Quellgeneratoren
- TypeInfoResolverChain
Änderungen an launchSettings.json
Die launchSettings.json
-Datei, die von der Web-API-Vorlage (native AOT-Kompilierung) erstellt wurde, hat den Abschnitt iisSettings
und das IIS Express
-Profil entfernt:
{
"$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"
- }
- }
}
}
Die CreateSlimBuilder
-Methode
Die Vorlage verwendet die CreateSlimBuilder()-Methode anstelle der CreateBuilder()-Methode.
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
{
}
Die CreateSlimBuilder
-Methode initialisiert WebApplicationBuilder mit den ASP.NET Core-Mindestfunktionen, die zum Ausführen einer App erforderlich sind.
Wie bereits erwähnt, bietet die CreateSlimBuilder
-Methode keine Unterstützung für HTTPS oder HTTP/3. Für Apps, die hinter einem TLS-Beendigungsproxy ausgeführt werden, sind diese Protokolle in der Regel nicht erforderlich. Beispiele finden Sie unter TLS-Abschluss und End-to-End-TSL mit Application Gateway. HTTPS kann durch Aufrufen von builder.WebHost.UseKestrelHttpsConfiguration aktiviert werden. HTTP/3 kann durch Aufrufen von builder.WebHost.UseQuic aktiviert werden.
CreateSlimBuilder
vs CreateBuilder
Die CreateSlimBuilder
-Methode unterstützt die folgenden Features, die von der CreateBuilder
-Methode unterstützt werden, nicht:
- Hostingstartassemblys
- UseStartup
- Die folgenden Protokollierungsanbieter:
- Webhostingfeatures:
- Kestrel-Konfiguration
- Beim Routing verwendete Regex- und Alpha-Einschränkungen
Die CreateSlimBuilder
-Methode enthält die folgenden Features, die für eine effiziente Entwicklungsumgebung erforderlich sind:
- JSON-Dateikonfiguration für
appsettings.json
undappsettings.{EnvironmentName}.json
. - Konfiguration der Benutzergeheimnisse.
- Konsolenprotokollierung.
- Konfiguration der Protokollierung.
Einen Generator, der die vorgenanntenFeatures überspringt, finden Sie unter Die CreateEmptyBuilder
-Methode.
Die Einbeziehung von minimalen Features besitzt Vorteile für das Kürzen sowie für AOT. Weitere Informationen finden Sie unter Kürzen eigenständiger Bereitstellungen und ausführbarer Dateien.
Ausführlichere Informationen finden Sie unter Vergleich von WebApplication.CreateBuilder
mit CreateSlimBuilder
.
Quellcode-Generatoren
Da nicht verwendeter Code während der Veröffentlichung für native AOT gekürzt wird, kann die App zur Laufzeit keine unbegrenzte Reflexion verwenden. Quellgeneratoren werden zum Generieren von Code verwendet, um die Notwendigkeit von Reflexion zu vermeiden. In einigen Fällen erzeugen Quellgeneratoren auch dann für AOT optimierten Code, wenn kein Generator erforderlich ist.
Um den generierten Quellcode anzuzeigen, fügen Sie die EmitCompilerGeneratedFiles
-Eigenschaft der Datei .csproj
einer App hinzu, wie im folgenden Beispiel gezeigt:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Other properties omitted for brevity -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
</Project>
Führen Sie den Befehl dotnet build
aus, um den generierten Code anzuzeigen. Die Ausgabe enthält ein Verzeichnis obj/Debug/net8.0/generated/
, das alle generierten Dateien für das Projekt enthält.
Der Befehl dotnet publish
kompiliert auch die Quelldateien und generiert Dateien, die kompiliert werden. Darüber hinaus übergibt dotnet publish
die generierten Assemblys an einen nativen IL-Compiler. Der IL-Compiler erzeugt die native ausführbare Datei. Die native ausführbare Datei enthält den nativen Computercode.
Bibliotheken und native AOT-Kompilierung
Viele der beliebten Bibliotheken, die in ASP.NET Core-Projekten verwendet werden, weisen derzeit einige Kompatibilitätsprobleme auf, wenn sie in einem Projekt für natives AOT verwendet werden, z. B.:
- Verwendung der Reflektion zum Untersuchen und Ermitteln von Typen.
- Bedingtes Laden von Bibliotheken zur Laufzeit.
- Automatisches Generieren von Code zum Implementieren von Funktionen.
Bibliotheken, die diese dynamischen Features verwenden, müssen aktualisiert werden, um mit nativem AOT zu funktionieren. Sie können mithilfe von Tools wie Roslyn-Quellgeneratoren aktualisiert werden.
Bibliotheksautoren, die natives AOT unterstützen möchten, wird Folgendes empfohlen:
- Lesen Sie mehr über die Kompatibilitätsanforderungen für natives AOT.
- Die Bibliothek für das Kürzen vorbereiten.
Minimale APIs und JSON-Nutzdaten
Das minimale API-Framework ist für das Empfangen und Zurückgeben von JSON-Nutzdaten mithilfe von System.Text.Json optimiert. System.Text.Json
:
- Legt Kompatibilitätsanforderungen für JSON und die native AOT-Kompilierung fest.
- Erfordert die Verwendung des
System.Text.Json
Quellgenerators.
Alle Typen, die als Teil des HTTP-Textkörpers übertragen oder von Anforderungsdelegaten in Minimal-API-Apps zurückgegeben werden, müssen für einen JsonSerializerContext konfiguriert werden, der über die Abhängigkeitsinjektion von ASP.NET Core registriert ist:
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
{
}
Im hervorgehobenen Code oben:
- Der JSON-Serialisierungskontext ist im DI-Container registriert. Weitere Informationen finden Sie unter .
- Kombinieren von Quellgeneratoren
- TypeInfoResolverChain
- Der benutzerdefinierte
JsonSerializerContext
wird mit dem Attribut[JsonSerializable]
versehen, um den aus der Quelle generierten JSON-Serialisierungscode für den TypToDo
zu aktivieren.
Ein Parameter für den Delegaten, der nicht an den Textkörper gebunden ist und nicht serialisierbar sein muss. Beispielsweise ein Abfragezeichenfolgenparameter, der ein umfangreicher Objekttyp ist und IParsable<T>
implementiert.
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.
Bekannte Probleme
In diesem GitHub-Issue können Sie Probleme mit der nativen AOT-Unterstützung in ASP.NET Core melden oder überprüfen.
Siehe auch
- Tutorial: Veröffentlichen einer ASP.NET Core-App mit nativer AOT-Kompilierung
- Native AOT-Bereitstellung
- Optimieren von AOT-Bereitstellungen
- Quell-Generator für Konfigurationsbindung
- Verwenden des Quell-Generators für die Konfigurationsbindung
- Die minimale AOT-Kompilierungsvorlage der API
- Vergleichen von
WebApplication.CreateBuilder
mitCreateSlimBuilder
- Erkunden des neuen minimalen API-Quell-Generators
- Ersetzen von Methodenaufrufen durch Interceptors
- Hinter
[LogProperties]
und dem neuen Generator für die Telemetrieprotokollierung
In ASP.NET Core 8.0 wird Unterstützung für native .NET-AOT-Kompilierung (Ahead-Of-Time) eingeführt.
Gründe für die Verwendung von nativer AOT-Kompilierung mit ASP.NET Core
Das Veröffentlichen und Bereitstellen einer nativen AOT-App bietet die folgenden Vorteile:
- Minimierter benötigter Speicherplatz auf dem Datenträger: Bei der Veröffentlichung mit nativer AOT-Kompilierung wird eine einzelne ausführbare Datei erstellt, die nur den Code aus externen Abhängigkeiten enthält, der zur Unterstützung des Programms erforderlich ist. Die reduzierte Größe ausführbarer Dateien kann zu Folgendem führen:
- Kleinere Containerimages, z. B. in Containerbereitstellungsszenarien
- Kürzere Bereitstellungsdauer durch kleinere Images
- Verkürzte Startzeit: Native AOT-Anwendungen können kürzere Startzeiten aufweisen. Dies bedeutet
- Die App kann Anforderungen schneller verarbeiten.
- Verbesserte Bereitstellung, bei der Containerorchestratoren den Übergang von einer Version der App zu einer anderen verwalten müssen
- Reduzierter Speicherbedarf: Native AOT-Apps können je nach den von der App ausgeführten Aktionen einen geringeren Speicherbedarf aufweisen. Eine reduzierte Arbeitsspeichernutzung kann zu einer höheren Bereitstellungsdichte und besserer Skalierbarkeit führen.
Die Vorlagen-App wurde in unserem Benchmark-Lab ausgeführt, um die Leistung einer mit AOT-Kompilierung veröffentlichten App, einer gekürzten Runtime-App und einer nicht gekürzten Runtime-App zu vergleichen. Die folgende Abbildung zeigt die Ergebnisse des Benchmarkings:
Die Abbildung oben zeigt, dass native AOT-Kompilierung eine geringere App-Größe, Arbeitsspeicherauslastung und Startzeit aufweist.
Kompatibilität von ASP.NET Core und nativer AOT-Kompilierung
Nicht alle Features in ASP.NET Core sind derzeit mit nativer AOT-Kompilierung kompatibel. In der folgenden Tabelle ist die Kompatibilität von ASP.NET Core-Features mit nativer AOT-Kompilierung zusammengefasst:
Funktion | Vollständig unterstützt | Teilweise unterstützt | Nicht unterstützt |
---|---|---|---|
gRPC | Vollständig unterstützt | ||
Minimale APIs | Teilweise unterstützt | ||
MVC | Nicht unterstützt | ||
Blazor Server | Nicht unterstützt | ||
SignalR | Nicht unterstützt | ||
JWT-Authentifizierung | Vollständig unterstützt | ||
Andere Authentifizierung | Nicht unterstützt | ||
CORS | Vollständig unterstützt | ||
HealthChecks | Vollständig unterstützt | ||
HttpLogging | Vollständig unterstützt | ||
Lokalisierung | Vollständig unterstützt | ||
OutputCaching | Vollständig unterstützt | ||
RateLimiting | Vollständig unterstützt | ||
RequestDecompression | Vollständig unterstützt | ||
ResponseCaching | Vollständig unterstützt | ||
ResponseCompression | Vollständig unterstützt | ||
Rewrite | Vollständig unterstützt | ||
Sitzung | Nicht unterstützt | ||
Spa | Nicht unterstützt | ||
StaticFiles | Vollständig unterstützt | ||
WebSockets | Vollständig unterstützt |
Weitere Informationen zu Beschränkungen finden Sie unter:
- Einschränkungen einer nativen AOT-Bereitstellung
- Einführung in AOT-Warnungen
- Bekannte Kürzungsinkompatibilitäten
- Einführung in Kürzungswarnungen
- GitHub issue dotnet/core #8288
Es ist wichtig, eine App gründlich zu testen, wenn Sie zu einem nativen AOT-Bereitstellungsmodell wechseln. Die über die AOT bereitgestellte App sollte getestet werden, um sicherzustellen, dass sich die Funktionalität im Vergleich zur nicht gekürzten und mit JIT kompilierten App nicht geändert hat. Überprüfen und korrigieren Sie AOT-Warnungen beim Erstellen der App. Eine App, die während der Veröffentlichung AOT-Warnungen erzeugt, funktioniert möglicherweise nicht ordnungsgemäß. Wenn zur Veröffentlichungszeit keine AOT-Warnungen ausgegeben werden, sollte die veröffentlichte AOT-App genauso funktionieren wie die ungetrimmte und JIT-kompilierte App.
Native AOT-Veröffentlichung
Native AOT-Kompilierung wird mit der MSBuild-Eigenschaft PublishAot
aktiviert. Das folgende Beispiel zeigt, wie systemeigene AOT-Kompilierung in einer Projektdatei aktiviert wird:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
Diese Einstellung aktiviert native AOT-Kompilierung während der Veröffentlichung und dynamische Analyse der Codeverwendung während des Build- und Bearbeitungsvorgangs. Ein Projekt, das die native AOT-Veröffentlichung verwendet, nutzt bei lokaler Ausführung die JIT-Kompilierung. Eine AOT-App weist die folgenden Unterschiede zu einer JIT-kompilierten App auf:
- Nicht mit nativer AOT-Kompilierung kompatible Features sind deaktiviert und lösen zur Laufzeit Ausnahmen aus.
- Ein Quellanalysetool ist aktiviert, um Code hervorzuheben, der nicht mit nativer AOT-Kompilierung kompatibel ist. Zum Zeitpunkt der Veröffentlichung wird die gesamte App, einschließlich NuGet-Paketen, erneut auf Kompatibilität analysiert.
Die Analyse der nativen AOT-Kompilierung umfasst den gesamten Code der App und die Bibliotheken, von der die App abhängig ist. Überprüfen Sie Warnungen der nativen AOT-Kompilierung und führen Sie Korrekturschritte durch. Es ist ratsam, Apps häufig zu veröffentlichen, um Probleme frühzeitig im Entwicklungslebenszyklus zu erkennen.
In .NET 8 wird native AOT-Kompilierung von den folgenden ASP.NET Core-App-Typen unterstützt:
- Minimale APIs – Weitere Informationen finden Sie weiter unten in diesem Artikel im Abschnitt Web-API-Vorlage (native AOT-Kompilierung).
- gRPC: Weitere Informationen finden Sie unter gRPC und native AOT-Kompilierung.
- Workerdienste: Weitere Informationen finden Sie unter AOT in Worker Service-Vorlagen.
Web-API-Vorlage (native AOT-Kompilierung)
Die ASP.NET Core-Web-API-Vorlage (native AOT-Kompilierung) (Kurzname webapiaot
) erstellt ein Projekt mit aktivierter AOT-Kompilierung. Die Vorlage unterscheidet sich wie folgt von der Web-API-Projektvorlage:
- Verwendet nur minimale APIs, da MVC noch nicht mit nativer AOT-Kompilierung kompatibel ist.
- Verwendet die CreateSlimBuilder()-API, um sicherzustellen, dass nur die wesentlichen Features standardmäßig aktiviert sind, wodurch die bereitgestellte Größe der App minimiert wird.
- Ist so konfiguriert, dass nur auf HTTP gelauscht wird, weil HTTPS-Datenverkehr in cloudnativen Bereitstellungen häufig von einem Eingangsdienst verarbeitet wird.
- Enthält kein Startprofil für die Ausführung unter IIS oder IIS Express.
- Erstellt eine
.http
-Datei, die mit HTTP-Beispielanforderungen konfiguriert ist, die an die Endpunkte der App gesendet werden können. - Enthält eine Beispiel-
Todo
-API anstelle des Beispiels für die Wettervorhersage. - Fügt
PublishAot
zur Projektdatei hinzu, wie weiter oben in diesem Artikel gezeigt. - Aktiviert die JSON-Serialisierer-Quellgeneratoren. Der Quellgenerator wird verwendet, um Serialisierungscode zur Buildzeit zu generieren. Dies ist für native AOT-Kompilierung erforderlich.
Änderungen zur Unterstützung von Quellgenerierung
Das folgende Beispiel zeigt den Code, welcher der Program.cs
-Datei hinzugefügt wurde, um die Generierung von JSON-Serialisierungsquellen zu unterstützen:
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
+{
+
+}
Ohne diesen zusätzlichen Code verwendet System.Text.Json
Reflexion zum Serialisieren und Deserialisieren von JSON. Reflexion wird in nativer AOT-Kompilierung nicht unterstützt.
Weitere Informationen finden Sie unter:
- Kombinieren von Quellgeneratoren
- TypeInfoResolverChain
Änderungen an launchSettings.json
Die launchSettings.json
-Datei, die von der Web-API-Vorlage (native AOT-Kompilierung) erstellt wurde, hat den Abschnitt iisSettings
und das IIS Express
-Profil entfernt:
{
"$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"
- }
- }
}
}
Die CreateSlimBuilder
-Methode
Die Vorlage verwendet die CreateSlimBuilder()-Methode anstelle der CreateBuilder()-Methode.
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
{
}
Die CreateSlimBuilder
-Methode initialisiert WebApplicationBuilder mit den ASP.NET Core-Mindestfunktionen, die zum Ausführen einer App erforderlich sind.
Wie bereits erwähnt, bietet die CreateSlimBuilder
-Methode keine Unterstützung für HTTPS oder HTTP/3. Für Apps, die hinter einem TLS-Beendigungsproxy ausgeführt werden, sind diese Protokolle in der Regel nicht erforderlich. Beispiele finden Sie unter TLS-Abschluss und End-to-End-TSL mit Application Gateway. HTTPS kann durch Aufrufen von builder.WebHost.UseKestrelHttpsConfiguration aktiviert werden. HTTP/3 kann durch Aufrufen von builder.WebHost.UseQuic aktiviert werden.
CreateSlimBuilder
vs CreateBuilder
Die CreateSlimBuilder
-Methode unterstützt die folgenden Features, die von der CreateBuilder
-Methode unterstützt werden, nicht:
- Hostingstartassemblys
- UseStartup
- Die folgenden Protokollierungsanbieter:
- Webhostingfeatures:
- Kestrel-Konfiguration
- Beim Routing verwendete Regex- und Alpha-Einschränkungen
Die CreateSlimBuilder
-Methode enthält die folgenden Features, die für eine effiziente Entwicklungsumgebung erforderlich sind:
- JSON-Dateikonfiguration für
appsettings.json
undappsettings.{EnvironmentName}.json
. - Konfiguration der Benutzergeheimnisse.
- Konsolenprotokollierung.
- Konfiguration der Protokollierung.
Einen Generator, der die vorgenanntenFeatures überspringt, finden Sie unter Die CreateEmptyBuilder
-Methode.
Die Einbeziehung von minimalen Features besitzt Vorteile für das Kürzen sowie für AOT. Weitere Informationen finden Sie unter Kürzen eigenständiger Bereitstellungen und ausführbarer Dateien.
Ausführlichere Informationen finden Sie unter Vergleich von WebApplication.CreateBuilder
mit CreateSlimBuilder
.
Quellcode-Generatoren
Da nicht verwendeter Code während der Veröffentlichung für native AOT gekürzt wird, kann die App zur Laufzeit keine unbegrenzte Reflexion verwenden. Quellgeneratoren werden zum Generieren von Code verwendet, um die Notwendigkeit von Reflexion zu vermeiden. In einigen Fällen erzeugen Quellgeneratoren auch dann für AOT optimierten Code, wenn kein Generator erforderlich ist.
Um den generierten Quellcode anzuzeigen, fügen Sie die EmitCompilerGeneratedFiles
-Eigenschaft der Datei .csproj
einer App hinzu, wie im folgenden Beispiel gezeigt:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Other properties omitted for brevity -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
</Project>
Führen Sie den Befehl dotnet build
aus, um den generierten Code anzuzeigen. Die Ausgabe enthält ein Verzeichnis obj/Debug/net8.0/generated/
, das alle generierten Dateien für das Projekt enthält.
Der Befehl dotnet publish
kompiliert auch die Quelldateien und generiert Dateien, die kompiliert werden. Darüber hinaus übergibt dotnet publish
die generierten Assemblys an einen nativen IL-Compiler. Der IL-Compiler erzeugt die native ausführbare Datei. Die native ausführbare Datei enthält den nativen Computercode.
Bibliotheken und native AOT-Kompilierung
Viele der beliebten Bibliotheken, die in ASP.NET Core-Projekten verwendet werden, weisen derzeit einige Kompatibilitätsprobleme auf, wenn sie in einem Projekt für natives AOT verwendet werden, z. B.:
- Verwendung der Reflektion zum Untersuchen und Ermitteln von Typen.
- Bedingtes Laden von Bibliotheken zur Laufzeit.
- Automatisches Generieren von Code zum Implementieren von Funktionen.
Bibliotheken, die diese dynamischen Features verwenden, müssen aktualisiert werden, um mit nativem AOT zu funktionieren. Sie können mithilfe von Tools wie Roslyn-Quellgeneratoren aktualisiert werden.
Bibliotheksautoren, die natives AOT unterstützen möchten, wird Folgendes empfohlen:
- Lesen Sie mehr über die Kompatibilitätsanforderungen für natives AOT.
- Die Bibliothek für das Kürzen vorbereiten.
Minimale APIs und JSON-Nutzdaten
Das minimale API-Framework ist für das Empfangen und Zurückgeben von JSON-Nutzdaten mithilfe von System.Text.Json optimiert. System.Text.Json
:
- Legt Kompatibilitätsanforderungen für JSON und die native AOT-Kompilierung fest.
- Erfordert die Verwendung des
System.Text.Json
Quellgenerators.
Alle Typen, die als Teil des HTTP-Textkörpers übertragen oder von Anforderungsdelegaten in Minimal-API-Apps zurückgegeben werden, müssen für einen JsonSerializerContext konfiguriert werden, der über die Abhängigkeitsinjektion von ASP.NET Core registriert ist:
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
{
}
Im hervorgehobenen Code oben:
- Der JSON-Serialisierungskontext ist im DI-Container registriert. Weitere Informationen finden Sie unter .
- Kombinieren von Quellgeneratoren
- TypeInfoResolverChain
- Der benutzerdefinierte
JsonSerializerContext
wird mit dem Attribut[JsonSerializable]
versehen, um den aus der Quelle generierten JSON-Serialisierungscode für den TypToDo
zu aktivieren.
Ein Parameter für den Delegaten, der nicht an den Textkörper gebunden ist und nicht serialisierbar sein muss. Beispielsweise ein Abfragezeichenfolgenparameter, der ein umfangreicher Objekttyp ist und IParsable<T>
implementiert.
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.
Bekannte Probleme
In diesem GitHub-Issue können Sie Probleme mit der nativen AOT-Unterstützung in ASP.NET Core melden oder überprüfen.
Siehe auch
- Tutorial: Veröffentlichen einer ASP.NET Core-App mit nativer AOT-Kompilierung
- Native AOT-Bereitstellung
- Optimieren von AOT-Bereitstellungen
- Quell-Generator für Konfigurationsbindung
- Verwenden des Quell-Generators für die Konfigurationsbindung
- Die minimale AOT-Kompilierungsvorlage der API
- Vergleichen von
WebApplication.CreateBuilder
mitCreateSlimBuilder
- Erkunden des neuen minimalen API-Quell-Generators
- Ersetzen von Methodenaufrufen durch Interceptors
- Hinter
[LogProperties]
und dem neuen Generator für die Telemetrieprotokollierung