Delen via


ASP.NET Core-ondersteuning voor systeemeigen AOT

Door Mitch Denny

ASP.NET Core 8.0 introduceert ondersteuning voor .NET native ahead-of-time (AOT).

Voor Blazor WebAssembly Native AOT-richtlijnen, die de richtlijnen in dit artikel toevoegen of vervangen, zie ASP.NET Core Blazor WebAssembly build tools en ahead-of-time (AOT) compilatie.

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 containerinstallatiekopieën, bijvoorbeeld in containerimplementatiescenario's.
    • 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 ✔️ gedeeltelijk ondersteund
JWT-verificatie ✔️ volledig ondersteund
Andere authenticatie Niet ondersteund
CORS ✔️ volledig ondersteund
Gezondheidscontroles ✔️ Volledig ondersteund
HttpLogging ✔️ volledig ondersteund
Lokalisatie ✔️ volledig ondersteund
OutputCaching (UitvoerCachen) ✔️ volledig ondersteund
Snelheidsbeperking ✔️ volledig ondersteunde
RequestDecompression ✔️ volledig ondersteund
Antwoordcaching ✔️ volledig ondersteund
ResponseCompression ✔️ 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 systeemeigen AOT-publicatie maakt gebruik van JIT-compilatie bij lokaal uitvoeren. 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.

Bibliotheken en systeemeigen AOT

Veel van de populaire bibliotheken die worden gebruikt in ASP.NET Core-projecten hebben momenteel enkele compatibiliteitsproblemen wanneer ze worden gebruikt in een project dat is gericht op systeemeigen AOT, zoals:

  • Gebruik van reflectie om typen te inspecteren en te ontdekken.
  • Bibliotheken voorwaardelijk laden tijdens runtime.
  • Code op het moment genereren om functionaliteit te implementeren.

Bibliotheken die deze dynamische functies gebruiken, moeten worden bijgewerkt om te kunnen werken met systeemeigen AOT. Ze kunnen worden bijgewerkt met behulp van hulpprogramma's zoals Roslyn-brongeneratoren.

Auteurs van bibliotheken die hopen native AOT te ondersteunen, worden aangemoedigd om:

Minimale API's en JSON-nettoladingen

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:

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

ASP.NET Core 8.0 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 scenario's voor containerimplementatie.
    • Verminderde uitvoeringstijd door kleinere afbeeldingen.
  • 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 sjabloon-app is uitgevoerd in ons benchmarkinglab 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 met de vergelijking van de metrische gegevens voor toepassingsgrootte, geheugengebruik en opstarttijd van een gepubliceerde AOT-app, een runtime-app die is gekrompen en een niet-gekrompen 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 APIs ✔️ gedeeltelijk ondersteund
MVC Niet ondersteund
Blazor Server Niet ondersteund
SignalR Niet ondersteund
JWT-verificatie ✔️ volledig ondersteund
Andere verificatie Niet ondersteund
CORS ✔️ volledig ondersteund
Gezondheidscontroles ✔️ volledig ondersteund
HttpLogging ✔️ volledig ondersteund
Lokalisatie ✔️ volledig ondersteund
OutputCaching ✔️ Volledig ondersteund
Snelheidsbegrenzing ✔️ volledig ondersteund
VerzoekDecompressie ✔️ volledig ondersteund
ResponseCaching ✔️ volledig ondersteund
ReactieCompressie 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 geïmplementeerde AOT-app moet worden getest om te controleren of de functionaliteit niet is gewijzigd ten opzichte van de niet-trimmed en JIT-gecompileerde app. Controleer en corrigeer AOT-waarschuwingen bij het bouwen van de app. Een app die AOT-waarschuwingen tijdens het publiceren, werkt mogelijk niet goed. Als er tijdens de publicatie geen AOT-waarschuwingen worden uitgegeven, moet de gepubliceerde AOT-app hetzelfde werken als de niet-bijgesneden en JIT-gecompileerde app.

Natieve 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 systeemeigen AOT-publicatie maakt gebruik van JIT-compilatie bij lokaal uitvoeren. 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 cloud-native implementaties.
  • 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 kunt u de JSON-serializer brongeneratoren inschakelen. 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 iisSettings sectie en het IIS Express profiel 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.
  • Configuratie van logboekregistratie.

Voor een bouwer die de voorgaande functies weglaat, zie de CreateEmptyBuilder methode.

Inclusief minimale functies heeft voordelen voor het bijsnijden en AOT. Zie voor meer informatie 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 uitvoering geen onbegrensde 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 systeemeigen uitvoerbare bestand bevat de systeemeigen computercode.

Bibliotheken en systeemeigen AOT

Veel van de populaire bibliotheken die worden gebruikt in ASP.NET Core-projecten hebben momenteel enkele compatibiliteitsproblemen wanneer ze worden gebruikt in een project dat is gericht op systeemeigen AOT, zoals:

  • Gebruik van reflectie om typen te inspecteren en te ontdekken.
  • Bibliotheken voorwaardelijk laden tijdens runtime.
  • Code op het moment genereren om functionaliteit te implementeren.

Bibliotheken die deze dynamische functies gebruiken, moeten worden bijgewerkt om te kunnen werken met systeemeigen AOT. Ze kunnen worden bijgewerkt met behulp van hulpprogramma's zoals Roslyn-brongeneratoren.

Auteurs van bibliotheken die hopen native AOT te ondersteunen, worden aangemoedigd om:

Minimale API's en JSON-nettoladingen

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 aanvraagafhandelaars in Minimal API-applicaties, moeten worden geconfigureerd op een JsonSerializerContext die is geregistreerd via dependency injection in 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
{

}

In de voorgaande gemarkeerde code:

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