ASP.NET Core-ondersteuning voor systeemeigen AOT

Door Mitch Denny

Het publiceren en implementeren van systeemeigen AOT-toepassingen (ahead-of-time) in ASP.NET Core biedt verschillende voordelen:

  • Geminimaliseerde schijfvoetafdruk. Wanneer u een app publiceert met behulp van systeemeigen AOT, produceert het proces één uitvoerbaar bestand. Het uitvoerbare bestand bevat alleen de code van de externe afhankelijkheden die nodig zijn om de app te ondersteunen. De kleinere uitvoerbare grootte kan leiden tot:

    • Kleinere containerafbeeldingen, bijvoorbeeld in containerimplementaties.
    • Verminderde implementatietijd met kleinere images.
  • Verminderde opstarttijd. Systeemeigen AOT-apps kunnen minder opstarttijd vereisen, waardoor:

    • De app voor snellere afhandeling van verzoeken.
    • Verbeterde implementatie, waarbij de containerorchestrators de overgang van de ene app-versie naar de andere beheren.
  • Verminderde geheugenvraag. Systeemeigen AOT-apps kunnen minder geheugen vereisen, afhankelijk van het werk dat door de app wordt uitgevoerd. Verminderd geheugenverbruik kan leiden tot een grotere implementatiedichtheid en verbeterde schaalbaarheid.

In de volgende grafiek ziet u de resultaten van een benchmarkingtest voor de verschillende sjabloon-apps. De benchmark vergelijkt de prestaties van een gepubliceerde AOT-app (oranje balk), een ingekorte runtime-app (groene balk) en een niet-ingekorte runtime-app (gele balk). Tijdens de test is gebleken dat de systeemeigen AOT-app lagere app-grootte, geheugengebruik en opstarttijd demonstreert.

Grafiek met een vergelijking van de metrische gegevens voor app-grootte, geheugengebruik en opstarttijd. De grafiek vergelijkt een gepubliceerde Native AOT-app, een bijgesneden runtime-app en een niet-opgehaalde runtime-app.

In dit artikel wordt de ondersteuning voor systeemeigen AOT-apps in ASP.NET Core beschreven, waaronder een overzicht van publiceren en implementeren.

Zie voor ASP.NET Core Blazor WebAssembly Systeemeigen AOT-richtlijnen, die de richtlijnen in dit artikel toevoegt of vervangt, ASP.NET Core Blazor WebAssembly build tools and ahead-of-time (AOT) compilatie.

Compatibiliteit met ASP.NET Core en systeemeigen AOT controleren

Niet alle functies in ASP.NET Core zijn momenteel compatibel met systeemeigen AOT.

De volgende tabel bevat een overzicht van ASP.NET Core-functiecompatibiliteit met systeemeigen AOT:

Kenmerk Supported Gedeeltelijke ondersteuning Niet ondersteund
Blazor Server
CORS (Cross-Origin Resource Sharing) ✔️
gRPC ✔️
Gezondheidscontroles ✔️
HTTP-logregistratie ✔️
JWT-verificatie ✔️
Lokalisatie ✔️
Minimale API's ✔️
MVC
Andere authenticatie
OutputCaching (UitvoerCachen) ✔️
Snelheidsbeperking ✔️
VerzoekOmDecompressie ✔️
Antwoordcaching ✔️
Antwoordcompressie ✔️
Herschrijven ✔️
Sessie
SignalR ✔️
Badplaats
StaticFiles ✔️
WebSockets ✔️

Zie voor meer informatie over beperkingen:

App controleren op het systeemeigen AOT-implementatiemodel

Het is belangrijk om een app grondig te testen wanneer u overstapt op een systeemeigen AOT-implementatiemodel. Test de geïmplementeerde AOT-app en bevestig dat de functionaliteit ongewijzigd is vergeleken met de niet-bijgesneden en just-in-time (JIT) gecompileerde app.

Wanneer u de app bouwt, controleert en corrigeert u alle AOT-waarschuwingen. Een app die AOT-waarschuwingen tijdens het publiceren opgeeft, werkt mogelijk niet goed. Als er tijdens het publiceren geen AOT-waarschuwingen worden uitgegeven, kunt u verwachten dat de gepubliceerde AOT-app hetzelfde werkt als de ongesnoeide en JIT-gecompileerde app.

Een systeemeigen AOT-app publiceren (PublishAot)

Schakel Systeemeigen AOT in voor uw toepassing met behulp van de PublishAot eigenschap MSBuild. In het volgende voorbeeld ziet u hoe u systeemeigen AOT inschakelt in een projectbestand:

<PropertyGroup>
  <PublishAot>true</PublishAot>
</PropertyGroup>

De PublishAot eigenschap schakelt systeemeigen AOT-compilatie in tijdens het publicatieproces en maakt dynamische codegebruiksanalyse mogelijk tijdens het bouwen en bewerken. Een project dat gebruikmaakt van systeemeigen AOT-publicatie implementeert JIT-compilatie wanneer het lokaal wordt uitgevoerd.

Een AOT-app heeft de volgende verschillen van een JIT-gecompileerde app:

  • Functies die niet compatibel zijn met systeemeigen AOT, worden uitgeschakeld en genereren uitzonderingen tijdens runtime.
  • Een bronanalyse is ingeschakeld om code te markeren die niet compatibel is met systeemeigen AOT. Tijdens de publicatie worden de volledige app, inclusief NuGet-pakketten, opnieuw geanalyseerd op compatibiliteit.

Systeemeigen AOT-analyse omvat alle toepassingscode en de bibliotheken waarvan de app afhankelijk is. Bekijk systeemeigen AOT-waarschuwingen en voer corrigerende stappen uit. Het is een goed idee om apps regelmatig te publiceren om problemen vroeg in de ontwikkelingslevenscyclus te detecteren.

In .NET 8 en hoger ondersteunen de volgende ASP.NET Core app-typen systeemeigen AOT:

De sjabloon web-API (systeemeigen AOT) controleren

Met de sjabloon ASP.NET Core Web-API (Native AOT) (korte naam webapiaot) wordt een project gemaakt waarvoor AOT is ingeschakeld. De sjabloon verschilt van een standaard web-API-projectsjabloon op de volgende manieren:

  • Maakt alleen gebruik van minimale API's, omdat MVC nog niet compatibel is met systeemeigen AOT.
  • Maakt gebruik van de CreateSlimBuilder() API om ervoor te zorgen dat alleen de essentiële functies standaard zijn ingeschakeld, waardoor de geïmplementeerde grootte van de app wordt geminimaliseerd.
  • Is geconfigureerd om alleen op HTTP te luisteren. HTTPS-verkeer wordt doorgaans verwerkt door een ingress-service in cloud-native-implementaties.
  • Bevat geen startprofiel voor uitvoering onder IIS of IIS Express.
  • Hiermee maakt u een HTTP-bestand dat is geconfigureerd met voorbeeld-HTTP-aanvragen die naar de eindpunten van de app kunnen worden verzonden.
  • Bevat een voorbeeld-Todo-API in plaats van het voorbeeld van de weersvoorspelling.
  • Voegt de PublishAot eigenschap toe aan het projectbestand, zoals eerder beschreven.
  • Hiermee worden de JSON serializer-brongeneratoren ingeschakeld. De brongenerator wordt gebruikt voor het genereren van serialisatiecode tijdens de build, die vereist is voor systeemeigen AOT-compilatie.

Code-updates voor JSON-serialisatie (Program.cs)

De code in het Program.cs-bestand wordt gewijzigd om ondersteuning te bieden voor het genereren van JSON-serialisatiebronnen.

In het volgende codefragment ziet u de wijzigingen in de code:

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
+{
+
+}

Als u de code niet wijzigt, System.Text.Json gebruikt u weerspiegeling om JSON te serialiseren en deserialiseren. Reflectie wordt niet ondersteund in Native AOT.

Zie voor meer informatie:

Codewijzigingen voor het startprofiel (launchSettings.json)

Met de sjabloon Web-API (Native AOT) wordt een launchSettings.json-bestand gemaakt. In tegenstelling tot een standaardlanceringsbestand bevat het gegenereerde bestand niet de iisSettings sectie of het IIS Express profiel.

In het volgende fragment ziet u de uitgesloten secties (rood gekleurd):

{
  "$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() aangeroepen voor minimale app-standaardinstellingen

De sjabloon Web-API (Native AOT) maakt gebruik van de CreateSlimBuilder() methode in plaats van de 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
{
}

De methode CreateSlimBuilder initialiseert de WebApplicationBuilder met de minimale ASP.NET Core-functies die nodig zijn om een app uit te voeren.

Zoals eerder beschreven, bevat de CreateSlimBuilder methode geen ondersteuning voor HTTPS of HTTP/3. Deze protocollen zijn doorgaans niet vereist voor apps die worden uitgevoerd achter een TLS-beëindigingsproxy. Zie bijvoorbeeld TLS-beëindiging en end-to-end TLS met Application Gateway. U kunt HTTPS inschakelen door de methode builder.WebHost.UseKestrelHttpsConfiguration aan te roepen, of HTTP/3 inschakelen door de methode builder.WebHost.UseQuic aan te roepen.

CreateSlimBuilder() en CreateBuilder() vergelijken

De CreateSlimBuilder methode biedt toegang tot een deel van de toepassingsfuncties die beschikbaar zijn voor de CreateBuilder methode. Zoals eerder beschreven, roept de sjabloon Web-API (Native AOT) sjabloon aan CreateSlimBuilder om WebApplicationBuilder te initialiseren, zodat de opbouwfunctie de minimale ASP.NET Core functies gebruikt die nodig zijn om de app uit te voeren.

Beide methoden bieden de benodigde functies voor een efficiënte ontwikkelervaring:

  • Configuratie voor de appsettings.json en appsettings.{ EnvironmentName}.json-bestanden
  • Configuratie van gebruikersgeheimen
  • Consolelogboekregistratie
  • Configuratie van logboekregistratie

Inclusief minimale functies heeft voordelen bij het bijsnijden en bij AOT. Voor meer informatie, zie Zelfstandige implementaties en uitvoerbare bestanden bijwerken.

Als u liever een opbouwfunctie gebruikt die alle functies weglaat, raadpleegt u de methode WebApplication.CreateEmptyBuilder .

Niet-beschikbare functies in CreateSlimBuilder

De CreateSlimBuilder methode biedt niet de volgende functies, die beschikbaar zijn in CreateBuilder:

Zie WebApplication.CreateBuilder vergelijken met CreateSlimBuilder voor meer gedetailleerde informatie

Brongeneratoren gebruiken en reflectie voorkomen

Tijdens het publicatieproces voor systeemeigen AOT wordt ongebruikte code ingekort. Als gevolg hiervan kan een app tijdens runtime geen niet-afhankelijke weerspiegeling gebruiken. U kunt brongeneratoren gebruiken die code produceren die de noodzaak van weerspiegeling voorkomt. In sommige gevallen is de uitvoercode van brongeneratoren geoptimaliseerd voor AOT, zelfs wanneer een generator niet vereist is.

  • Als u de gegenereerde broncode wilt weergeven, voegt u de eigenschap EmitCompilerGeneratedFiles toe aan het toepassingsprojectbestand (.csproj):

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
       <PropertyGroup>
         <!-- Other properties omitted for brevity -->
         <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
       </PropertyGroup>
    
    </Project>
    
  • Voer de opdracht uit om de dotnet build gegenereerde code te zien. Met de opdracht worden de bronbestanden gecompileerd en worden de tussenliggende bestanden gegenereerd die nodig zijn om de app uit te voeren in een ontwikkelomgeving. De uitvoer bevat een obj/Debug/<.NET version>/generated/ map die alle gegenereerde bestanden voor het project bevat.

  • Voer dotnet publish de opdracht uit om de app voor te bereiden op implementatie. Met de opdracht worden de bronbestanden gecompileerd en worden alle bestanden gegenereerd die nodig zijn om de app te implementeren. De gegenereerde assembly's worden doorgegeven aan een systeemeigen IL-compiler, waardoor het systeemeigen uitvoerbare bestand wordt geproduceerd. Het uitvoerbare bestand bevat de natuurlijke machinecode.

Gebruik bibliotheken met Native AOT

Veel populaire bibliotheken die worden gebruikt in ASP.NET Core projecten hebben momenteel enkele compatibiliteitsproblemen wanneer ze zijn opgenomen in projecten die gericht zijn op systeemeigen AOT, zoals:

  • Reflectie gebruiken om typen te inspecteren en te ontdekken
  • Bibliotheken voorwaardelijk laden tijdens runtime
  • Code op het moment genereren om functionaliteit te implementeren

Voor bibliotheken die gebruikmaken van deze dynamische functies zijn updates vereist voor gebruik met systeemeigen AOT. Er zijn verschillende hulpprogramma's beschikbaar voor het toepassen van de benodigde updates, zoals Roslyn-brongeneratoren.

Auteurs van bibliotheken die hopen om Native AOT te ondersteunen, worden aangemoedigd om de volgende artikelen te bekijken:

Werken met minimale API's en JSON-nettoladingen

Het minimale API-framework is geoptimaliseerd voor het ontvangen en retourneren van JSON-payloads met behulp van de System.Text.Json.

Alle typen die worden verzonden als onderdeel van de HTTP-body of die worden geretourneerd door request-afhandelaars in Minimal API-apps, moeten worden geconfigureerd op een JsonSerializerContext exemplaar. Het exemplaar moet worden geregistreerd bij ASP.NET Core dependency injection.

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
{
}

Een parameter voor de gemachtigde die niet aan de hoofdtekst is gebonden , hoeft niet serialiseerbaar te zijn. Een querytekenreeksparameter kan bijvoorbeeld een complex objecttype zijn dat IParsable<T> implementeert.

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.

Bekende problemen bekijken

Zie GitHub /dotnet/core/issues #8288) om problemen met systeemeigen AOT-ondersteuning in ASP.NET Core te rapporteren of te bekijken.

.NET 8 introduceert ondersteuning voor .NET native ahead-of-time (AOT).

Waarom Systeemeigen AOT gebruiken met ASP.NET Core

Het publiceren en implementeren van een systeemeigen AOT-app biedt de volgende voordelen:

  • geminimaliseerde schijfvoetafdruk: bij het publiceren met systeemeigen AOT wordt één uitvoerbaar bestand geproduceerd dat alleen de code bevat van externe afhankelijkheden die nodig zijn om het programma te ondersteunen. Beperkte uitvoerbare grootte kan leiden tot:
    • Kleinere containerafbeeldingen, bijvoorbeeld in containerimplementaties.
    • Verminderde implementatietijd met kleinere images.
  • verkorte opstarttijd: Systeemeigen AOT-toepassingen kunnen verminderde opstarttijden weergeven, wat betekent dat
    • De app is gereed voor het sneller verwerken van aanvragen.
    • Verbeterde implementatie waarbij containerorchestrators de overgang van de ene versie van de app naar een andere moeten beheren.
  • verminderde geheugenvraag: systeemeigen AOT-apps kunnen minder geheugenvereisten hebben, afhankelijk van het werk dat door de app wordt uitgevoerd. Verminderd geheugenverbruik kan leiden tot een grotere implementatiedichtheid en verbeterde schaalbaarheid.

De template-app is uitgevoerd in ons benchmarking-lab om de prestaties van een gepubliceerde AOT-app, een bijgesneden runtime-app en een niet-bijgesneden runtime-app te vergelijken. In de volgende grafiek ziet u de resultaten van de benchmarking:

diagram dat de vergelijking toont van de metrische gegevens van applicatiegrootte, geheugengebruik en opstarttijd van een gepubliceerde AOT-app, een afgeslankte runtime-app en een niet-ingekorte runtime-app.

In de voorgaande grafiek ziet u dat Systeemeigen AOT een lagere app-grootte, geheugengebruik en opstarttijd heeft.

ASP.NET Core- en Systeemeigen AOT-compatibiliteit

Niet alle functies in ASP.NET Core zijn momenteel compatibel met systeemeigen AOT. De volgende tabel bevat een overzicht van ASP.NET Core-functiecompatibiliteit met systeemeigen AOT:

Kenmerk Volledig ondersteund Gedeeltelijk ondersteund Niet ondersteund
gRPC ✔️ volledig ondersteund
Minimale API's ✔️ gedeeltelijk ondersteund
MVC Niet ondersteund
Blazor Server Niet ondersteund
SignalR Niet ondersteund
JWT-verificatie ✔️ volledig ondersteund
Andere authenticatie Niet ondersteund
CORS (Cross-Origin Resource Sharing) ✔️ volledig ondersteund
Gezondheidscontroles ✔️ volledig ondersteund
HTTP-logregistratie ✔️ volledig ondersteund
Lokalisatie ✔️ volledig ondersteund
OutputCaching (UitvoerCachen) ✔️ volledig ondersteund
Snelheidsbeperking ✔️ volledig ondersteund
VerzoekOmDecompressie ✔️ volledig ondersteund
Antwoordcaching ✔️ volledig ondersteund
Antwoordcompressie ✔️ volledig ondersteund
Herschrijven ✔️ volledig ondersteund
Sessie Niet ondersteund
Badplaats Niet ondersteund
StaticFiles ✔️ volledig ondersteund
WebSockets ✔️ volledig ondersteund

Zie voor meer informatie over beperkingen:

Het is belangrijk om een app grondig te testen wanneer u overstapt op een systeemeigen AOT-implementatiemodel. De uitgerolde AOT-app moet worden getest om te controleren of de functionaliteit nog steeds overeenkomt met die van de niet-bijgesneden en JIT-gecompileerde app. Controleer en corrigeer AOT-waarschuwingen bij het bouwen van de app. Een app die AOT-waarschuwingen geeft tijdens het publiceren, werkt mogelijk niet goed. Als er bij het publiceren geen AOT-waarschuwingen worden uitgegeven, moet de gepubliceerde AOT-app op dezelfde manier werken als de niet-gesnoeide en JIT-gecompileerde app.

Systeemeigen AOT-publicatie

Native AOT is ingeschakeld met de MSBuild-eigenschap PublishAot. In het volgende voorbeeld ziet u hoe u systeemeigen AOT inschakelt in een projectbestand:

<PropertyGroup>
  <PublishAot>true</PublishAot>
</PropertyGroup>

Deze instelling maakt systeemeigen AOT-compilatie mogelijk tijdens het publiceren en maakt dynamische analyse van codegebruik mogelijk tijdens het bouwen en bewerken. Een project dat gebruikmaakt van native AOT-publicatie, voert lokaal JIT-compilatie uit. Een AOT-app heeft de volgende verschillen van een JIT-gecompileerde app:

  • Functies die niet compatibel zijn met systeemeigen AOT, worden uitgeschakeld en genereren uitzonderingen tijdens runtime.
  • Een bronanalyse is ingeschakeld om code te markeren die niet compatibel is met systeemeigen AOT. Tijdens de publicatie worden de volledige app, inclusief NuGet-pakketten, opnieuw geanalyseerd op compatibiliteit.

Systeemeigen AOT-analyse omvat alle code van de app en de bibliotheken waarvan de app afhankelijk is. Bekijk systeemeigen AOT-waarschuwingen en voer corrigerende stappen uit. Het is een goed idee om apps regelmatig te publiceren om problemen vroeg in de ontwikkelingslevenscyclus te detecteren.

In .NET 8 wordt native AOT ondersteund door de volgende ASP.NET Core-app-typen:

De web-API-sjabloon (systeemeigen AOT)

Met de ASP.NET Core Web API (Native AOT) sjabloon (korte naam webapiaot) wordt een project gemaakt waarvoor AOT is ingeschakeld. De sjabloon verschilt van de Web-API projectsjabloon op de volgende manieren:

  • Maakt alleen gebruik van minimale API's, omdat MVC nog niet compatibel is met systeemeigen AOT.
  • Maakt gebruik van de CreateSlimBuilder()-API om ervoor te zorgen dat alleen de essentiële functies standaard zijn ingeschakeld, waardoor de geïmplementeerde grootte van de app wordt geminimaliseerd.
  • Is geconfigureerd om alleen op HTTP te luisteren, omdat HTTPS-verkeer doorgaans wordt verwerkt door een ingress-service in cloudimplementaties.
  • Bevat geen startprofiel voor uitvoering onder IIS of IIS Express.
  • Hiermee maakt u een .http-bestand geconfigureerd met voorbeeld-HTTP-aanvragen die naar de eindpunten van de app kunnen worden verzonden.
  • Bevat een voorbeeld-Todo-API in plaats van het voorbeeld van de weersvoorspelling.
  • Voegt PublishAot toe aan het projectbestand, zoals eerder in dit artikel wordt weergegeven.
  • Hiermee worden de JSON serializer-brongeneratoren ingeschakeld. De brongenerator wordt gebruikt voor het genereren van serialisatiecode tijdens de build, die vereist is voor systeemeigen AOT-compilatie.

Wijzigingen in het ondersteunen van brongeneratie

In het volgende voorbeeld ziet u de code die is toegevoegd aan het Program.cs-bestand ter ondersteuning van het genereren van JSON-serialisatiebronnen:

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
+{
+
+}

Zonder deze toegevoegde code gebruikt System.Text.Json weerspiegeling om JSON te serialiseren en deserialiseren. Reflectie wordt niet ondersteund in Native AOT.

Zie voor meer informatie:

Wijzigingen in launchSettings.json

Het launchSettings.json-bestand dat is gemaakt door de Web-API (Native AOT)-sjabloon, heeft de sectie iisSettings en het profiel IIS Express verwijderd.

{
  "$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"
-      }
-    }
  }
}

De methode CreateSlimBuilder

De sjabloon gebruikt de methode CreateSlimBuilder() in plaats van de methode 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
{
}

De methode CreateSlimBuilder initialiseert de WebApplicationBuilder met de minimale ASP.NET Core-functies die nodig zijn om een app uit te voeren.

Zoals eerder vermeld, bevat de methode CreateSlimBuilder geen ondersteuning voor HTTPS of HTTP/3. Deze protocollen zijn doorgaans niet vereist voor apps die worden uitgevoerd achter een TLS-beëindigingsproxy. Zie bijvoorbeeld TLS-beëindiging en end-to-end TLS met Application Gateway. HTTPS kan worden ingeschakeld door builder aan te roepen. WebHost.UseKestrelHttpsConfiguration HTTP/3 kan worden ingeschakeld door builder aan te roepen. WebHost.UseQuic.

CreateSlimBuilder versus CreateBuilder

De methode CreateSlimBuilder biedt geen ondersteuning voor de volgende functies die worden ondersteund door de methode CreateBuilder:

De methode CreateSlimBuilder bevat de volgende functies die nodig zijn voor een efficiënte ontwikkelervaring:

  • JSON-bestandsconfiguratie voor appsettings.json en appsettings.{EnvironmentName}.json.
  • Configuratie van gebruikersgeheimen.
  • Consolelogboekregistratie.
  • Logboekinstellingen.

Zie de CreateEmptyBuilder methodevoor een builder die de voorgaande functies weglaat.

Inclusief minimale functies heeft voordelen bij het bijsnijden en bij AOT. Voor meer informatie, zie Zelfstandige implementaties en uitvoerbare bestanden bijwerken.

Zie WebApplication.CreateBuilder vergelijken met CreateSlimBuilder voor meer gedetailleerde informatie

Brongeneratoren

Omdat ongebruikte code tijdens het publiceren voor native AOT wordt beperkt, kan de app tijdens runtime geen onbeperkte reflectie gebruiken. Brongeneratoren worden gebruikt om code te produceren die de noodzaak van reflectie voorkomt. In sommige gevallen produceren brongeneratoren code die is geoptimaliseerd voor AOT, zelfs wanneer een generator niet vereist is.

Als u de gegenereerde broncode wilt weergeven, voegt u de eigenschap EmitCompilerGeneratedFiles toe aan het .csproj-bestand van een app, zoals wordt weergegeven in het volgende voorbeeld:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <!-- Other properties omitted for brevity -->
    <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
  </PropertyGroup>

</Project>

Voer de opdracht dotnet build uit om de gegenereerde code weer te geven. De uitvoer bevat een obj/Debug/net8.0/generated/ map met alle gegenereerde bestanden voor het project.

Met de opdracht dotnet publish worden ook de bronbestanden gecompileerd en worden bestanden gegenereerd die zijn gecompileerd. Bovendien geeft dotnet publish de gegenereerde assembly's door aan een systeemeigen IL-compiler. De IL-compiler produceert het systeemeigen uitvoerbare bestand. Het uitvoerbare bestand bevat de natuurlijke machinecode.

Gebruik bibliotheken met Native AOT

Veel populaire bibliotheken die worden gebruikt in ASP.NET Core projecten hebben momenteel enkele compatibiliteitsproblemen wanneer ze zijn opgenomen in projecten die gericht zijn op systeemeigen AOT, zoals:

  • Reflectie gebruiken om typen te inspecteren en te ontdekken
  • Bibliotheken voorwaardelijk laden tijdens runtime
  • Code op het moment genereren om functionaliteit te implementeren

Voor bibliotheken die gebruikmaken van deze dynamische functies zijn updates vereist voor gebruik met systeemeigen AOT. Er zijn verschillende hulpprogramma's beschikbaar voor het toepassen van de benodigde updates, zoals Roslyn-brongeneratoren.

Auteurs van bibliotheken die hopen om Native AOT te ondersteunen, worden aangemoedigd om de volgende artikelen te bekijken:

Minimale API's en JSON-belastingen

Het minimale API-framework is geoptimaliseerd voor het ontvangen en retourneren van JSON-nettoladingen met behulp van System.Text.Json. System.Text.Json:

Alle typen die worden verzonden als onderdeel van de HTTP-hoofdtekst of die worden geretourneerd door verzoekdelegaten in Minimal API-apps, moeten worden geconfigureerd op een JsonSerializerContext die via de dependency injection van ASP.NET Core is geregistreerd.

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
{
}

In de voorgaande gemarkeerde code:

  • De context van de JSON-serialisatiefunctie wordt geregistreerd bij de DI-container. Zie voor meer informatie:
  • De aangepaste JsonSerializerContext wordt geannoteerd met het kenmerk [JsonSerializable] om de door de bron gegenereerde JSON-serializercode voor het ToDo type in te schakelen.

Een parameter voor de gemachtigde die niet is gebonden aan de hoofdtekst en niet serialiseerbaar moet zijn. Een queryreeksparameter die bijvoorbeeld een uitgebreid objecttype is en IParsable<T>implementeert.

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.

Bekende problemen

Zie dit GitHub-probleem om problemen met systeemeigen AOT-ondersteuning in ASP.NET Core te melden of te bekijken.

Zie ook