Dela via


ASP.NET Core-stöd för intern AOT

Av Mitch Denny

ASP.NET Core 8.0 introducerar stöd för .NET-inbyggt i förväg (AOT).

Vägledning för Blazor WebAssembly native AOT, som lägger till eller ersätter vägledningen i den här artikeln, finns i ASP.NET Core Blazor WebAssembly build tools and ahead-of-time (AOT) compilation.

Varför använda intern AOT med ASP.NET Core

Att publicera och distribuera en intern AOT-app ger följande fördelar:

  • Minimerat diskavtryck: När du publicerar med intern AOT skapas en enda körbar fil som bara innehåller koden från externa beroenden som behövs för att stödja programmet. Minskad körbar storlek kan leda till:
    • Mindre containeravbildningar, till exempel i scenarier med containerbaserad distribution.
    • Minskad implementeringstid med mindre bilder.
  • Minskad starttid: Interna AOT-program kan visa minskade starttider, vilket innebär att
    • Appen är redo att skicka begäranden snabbare.
    • Förbättrad distribution där containerorkestrerare behöver hantera övergången från en version av appen till en annan.
  • Minskad minnesefterfrågan: Interna AOT-appar kan ha lägre minnesbehov, beroende på vilket arbete som utförs av appen. Minskad minnesförbrukning kan leda till större distributionsdensitet och förbättrad skalbarhet.

Mallappen kördes i vårt benchmarkinglaboratorium för att jämföra prestanda för en AOT-publicerad app, en app med trimmad körningstid och en app med otrimmad körningstid. Följande diagram visar resultatet av benchmarking:

diagram som visar jämförelse av programstorlek, minnesanvändning och starttidsmått för en AOT-publicerad app, en körningsapp som trimmas och en otrimmad körningsapp.

Föregående diagram visar att intern AOT har lägre appstorlek, minnesanvändning och starttid.

ASP.NET Core och intern AOT-kompatibilitet

Alla funktioner i ASP.NET Core är för närvarande inte kompatibla med intern AOT. I följande tabell sammanfattas ASP.NET Core-funktionskompatibilitet med intern AOT:

Funktion Stöds fullt ut Delvis stöd Stöds inte
gRPC ✔️ stöds
Minimala API:er ✔️ delvis stöds
MVC Stöds inte
Blazor Server Stöds inte
SignalR ✔️ stöds delvis
JWT-autentisering ✔️ stöds fullt ut
Annan autentisering Stöds inte
CORS (Cross-Origin Resource Sharing) ✔️ helt stöds
Hälsokontroller ✔️ stöds
HttpLogging ✔️ stöds fullt ut
Lokalisering ✔️ stöds fullt
OutputCaching ✔️ stöds helt
Hastighetsbegränsning ✔️ stöds
BegäranOmDekomprimering ✔️ stöds fullt ut
Svarcachning ✔️ stöds fullt ut
Svarskomprimering ✔️ stöds
Skriv om ✔️ Fullt stöd
Session Stöds inte
Brunn Stöds inte
StaticFiles ✔️ stödjs fullständigt
WebSockets Fullt stöds

Mer information om begränsningar finns i:

Det är viktigt att testa en app noggrant när du flyttar till en intern AOT-distributionsmodell. Den AOT-distribuerade appen bör testas för att kontrollera att funktionaliteten inte har ändrats från den otrimmade och JIT-kompilerade appen. När du skapar appen granskar och korrigerar du AOT-varningar. En app som utfärdar AOT-varningar vid publicering kanske inte fungerar korrekt. Om inga AOT-varningar utfärdas vid publiceringstillfället bör den publicerade AOT-appen fungera på samma sätt som den otrimmade och JIT-kompilerade appen.

Native AOT-publicering

Native AOT är aktiverat med PublishAot MSBuild-egenskapen. I följande exempel visas hur du aktiverar intern AOT i en projektfil:

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

Den här inställningen aktiverar intern AOT-kompilering under publiceringen och möjliggör dynamisk kodanvändningsanalys under kompilering och redigering. Ett projekt som använder intern AOT-publicering använder JIT-kompilering när det körs lokalt. En AOT-app har följande skillnader från en JIT-kompilerad app:

  • Funktioner som inte är kompatibla med Native AOT inaktiveras och utlöser undantag vid exekvering.
  • En källanalys har aktiverats för att markera kod som inte är kompatibel med intern AOT. Vid publiceringen analyseras hela appen, inklusive NuGet-paket, för kompatibilitet igen.

Intern AOT-analys innehåller all appkod och de bibliotek som appen är beroende av. Granska interna AOT-varningar och vidta korrigerande åtgärder. Det är en bra idé att publicera appar ofta för att upptäcka problem tidigt i utvecklingslivscykeln.

I .NET 8 stöds intern AOT av följande ASP.NET Core-apptyper:

Mallen Web API (Native AOT)

Mallen ASP.NET Core Web API (Native AOT) (kortnamn webapiaot) skapar ett projekt med AOT aktiverat. Mallen skiljer sig från webb-API projektmall på följande sätt:

  • Använder endast minimala API:er eftersom MVC ännu inte är kompatibelt med intern AOT.
  • Använder CreateSlimBuilder()-API:et för att säkerställa att endast de viktigaste funktionerna är aktiverade som standard, vilket minimerar appens distribuerade storlek.
  • Är konfigurerad för att lyssna endast på HTTP eftersom HTTPS-trafik ofta hanteras av en ingresstjänst i molnbaserade distributioner.
  • Innehåller inte någon startprofil för körning under IIS eller IIS Express.
  • Skapar en .http fil konfigurerad med HTTP-exempelbegäranden som kan skickas till appens slutpunkter.
  • Innehåller ett exempel Todo API i stället för väderprognosexemplet.
  • Lägger till PublishAot i projektfilen, som visades tidigare i den här artikeln.
  • Aktiverar JSON-serialiserarens källgeneratorer. Källgeneratorn används för att generera serialiseringskod vid byggtiden, vilket krävs för intern AOT-kompilering.

Ändringar för att stödja källgenerering

I följande exempel visas koden som lagts till i Program.cs-filen för att stödja JSON-serialiseringskällans generering:

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

Utan den här extra koden använder System.Text.Json reflektion för att serialisera och deserialisera JSON. Reflektion stöds inte i Native AOT.

Mer information finns i:

Ändringar i launchSettings.json

Den launchSettings.json fil som skapats av mallen Web API (Native AOT) har iisSettings-avsnittet och IIS Express profilen borttagen:

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

Metoden CreateSlimBuilder

Mallen använder metoden CreateSlimBuilder() i stället för metoden 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
{

}

Metoden CreateSlimBuilder initierar WebApplicationBuilder med de minsta ASP.NET Core-funktioner som krävs för att köra en app.

Som tidigare nämnts innehåller metoden CreateSlimBuilder inte stöd för HTTPS eller HTTP/3. Dessa protokoll krävs vanligtvis inte för appar som körs bakom en TLS-avslutningsproxy. Se exempelvis TLS-avslutning och end-to-end TLS med Application Gateway. HTTPS kan aktiveras genom att anropa builder. WebHost.UseKestrelHttpsConfiguration HTTP/3 kan aktiveras genom att anropa builder. WebHost.UseQuic.

CreateSlimBuilder jämfört med CreateBuilder

Metoden CreateSlimBuilder stöder inte följande funktioner som stöds av metoden CreateBuilder:

Metoden CreateSlimBuilder innehåller följande funktioner som behövs för en effektiv utvecklingsupplevelse:

  • JSON-filkonfiguration för appsettings.json och appsettings.{EnvironmentName}.json.
  • Konfiguration av användarhemligheter.
  • Konsolloggning.
  • Loggningskonfiguration.

För en byggare som utelämnar de föregående funktionerna, se Metoden CreateEmptyBuilder.

Att inkludera minimala funktioner har fördelar både för trimning och för AOT. Mer information finns i "Trimma fristående applikationer och körbara filer."

Mer detaljerad information finns i Jämföra WebApplication.CreateBuilder med CreateSlimBuilder

Källgeneratorer

Eftersom oanvänd kod trimmas under publiceringen för Native AOT kan appen inte använda obunden reflektion vid körning. Källkodsgeneratorer används för att skapa kod som eliminerar behovet av reflektion. I vissa fall producerar källgeneratorer kod optimerad för AOT även när en generator inte krävs.

Om du vill visa källkoden som genereras lägger du till egenskapen EmitCompilerGeneratedFiles i en apps .csproj fil, enligt följande exempel:

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

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

</Project>

Kör kommandot dotnet build för att se den genererade koden. Utdata innehåller en obj/Debug/net8.0/generated/ katalog som innehåller alla genererade filer för projektet.

Kommandot dotnet publish kompilerar också källfilerna och genererar filer som kompileras. Dessutom skickar dotnet publish de genererade sammansättningarna till en intern IL-kompilator. IL-kompilatorn producerar det ursprungliga körbara programmet. Den inhemska körbara filen innehåller den inhemska maskinkoden.

Bibliotek och intern AOT

Många av de populära bibliotek som används i ASP.NET Core-projekt har för närvarande vissa kompatibilitetsproblem när de används i ett projekt som riktar sig till intern AOT, till exempel:

  • Använd reflektion för att inspektera och identifiera typer.
  • Villkorlig inläsning av bibliotek vid exekvering.
  • Generera kod i farten för att implementera funktioner.

Bibliotek som använder dessa dynamiska funktioner måste uppdateras för att fungera med intern AOT. De kan uppdateras med hjälp av verktyg som Roslyn-källgeneratorer.

Biblioteksförfattare som hoppas kunna stödja native AOT uppmuntras att:

Minimala API:er och JSON-nyttolaster

Det minimala API-ramverket är optimerat för att ta emot och returnera JSON-nyttolaster med hjälp av System.Text.Json. System.Text.Json:

Alla typer som överförs som en del av HTTP-kroppen eller returneras av förfrågningsdelegerare i appar med enkla API:er måste konfigureras på en JsonSerializerContext som registreras via ASP.NET Cores beroendeinjektion.

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
{

}

I föregående markerade kod:

Parametern på delegaten som inte är bunden till kroppen och inte behöver vara serialiserbar. Till exempel en frågesträngsparameter som är en omfattande objekttyp och implementerar IParsable<T>.

public class Todo
{
    public int Id { get; set; }
    public string? Title { get; set; }
    public DateOnly? DueBy { get; set; }
    public bool IsComplete { get; set; }
}

static class TodoGenerator
{
    private static readonly (string[] Prefixes, string[] Suffixes)[] _parts = new[]
        {
            (new[] { "Walk the", "Feed the" }, new[] { "dog", "cat", "goat" }),
            (new[] { "Do the", "Put away the" }, new[] { "groceries", "dishes", "laundry" }),
            (new[] { "Clean the" }, new[] { "bathroom", "pool", "blinds", "car" })
        };
    // Remaining code omitted for brevity.

Kända problem

Se det här GitHub-problemet för att rapportera eller granska problem med inbyggt AOT-stöd i ASP.NET Core.

Se även

ASP.NET Core 8.0 introducerar stöd för .NET native ahead-of-time (AOT).

Varför använda intern AOT med ASP.NET Core

Att publicera och distribuera en intern AOT-app ger följande fördelar:

  • Minimerat diskavtryck: När du publicerar med intern AOT skapas en enda körbar fil som bara innehåller koden från externa beroenden som behövs för att stödja programmet. Minskad körbar storlek kan leda till:
    • Mindre containeravbildningar, till exempel i scenarier med containerbaserad distribution.
    • Minskad utrullningstid från mindre bilder.
  • Minskad starttid: Interna AOT-program kan visa minskade starttider, vilket innebär att
    • Appen är redo att skicka begäranden snabbare.
    • Förbättrad distribution där containerorkestrerare behöver hantera övergången från en version av appen till en annan.
  • Minskad minnesefterfrågan: Interna AOT-appar kan ha lägre minnesbehov, beroende på vilket arbete som utförs av appen. Minskad minnesförbrukning kan leda till större distributionsdensitet och förbättrad skalbarhet.

Mallappen kördes i vårt benchmarking-labb för att jämföra prestanda för en AOT-publicerad app, en trimmad körningsapp och en otrimmad körningsapp. Följande diagram visar resultatet av benchmarking:

diagram som visar jämförelse av programstorlek, minnesanvändning och starttidsmått för en AOT-publicerad app, en körningsapp som trimmas och en otrimmad körningsapp.

Föregående diagram visar att intern AOT har lägre appstorlek, minnesanvändning och starttid.

ASP.NET Core och intern AOT-kompatibilitet

Alla funktioner i ASP.NET Core är för närvarande inte kompatibla med intern AOT. I följande tabell sammanfattas ASP.NET Core-funktionskompatibilitet med intern AOT:

Funktion Stöds fullt ut Delvis stöd Stöds inte
gRPC ✔️ stöds
Minimala API:er ✔️ stöds delvis
MVC Stöds inte
Blazor Server Stöds inte
SignalR Stöds inte
JWT-autentisering ✔️ stöds helt
Annan autentisering Stöds inte
CORS (Cross-Origin Resource Sharing) stöds fullt ut
Hälsokontroller ✔️ stöds
http-protokollering ✔️ stöds
Lokalisering ✔️ stöds fullt
Cachelagring av utdata Helt stöds
Hastighetsbegränsning ✔️ stöds fullt ut
BegäranAvkomprimering ✔️ stöds
Svarscachning ✔️ stöds fullt ut
SvarsKompression ✔️ stöds
Skriv om ✔️ stöds
Session Stöds inte
Brunn Stöds inte
StaticFiles ✔️ stöds
WebSockets Fullt stöds

Mer information om begränsningar finns i:

Det är viktigt att testa en app noggrant när du flyttar till en intern AOT-distributionsmodell. Den AOT-distribuerade appen bör testas för att kontrollera att funktionaliteten inte har ändrats från den otrimmade och JIT-kompilerade appen. När du skapar appen granskar och korrigerar du AOT-varningar. En app som utfärdar AOT-varningar vid publicering kanske inte fungerar korrekt. Om inga AOT-varningar utfärdas vid publiceringstillfället bör den publicerade AOT-appen fungera på samma sätt som den otrimmade och JIT-kompilerade appen.

Inbyggd AOT-publicering

Native AOT är aktiverat med egenskapen PublishAot MSBuild. I följande exempel visas hur du aktiverar intern AOT i en projektfil:

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

Den här inställningen aktiverar intern AOT-kompilering under publiceringen och möjliggör dynamisk kodanvändningsanalys under kompilering och redigering. Ett projekt som använder intern AOT-publicering använder JIT-kompilering när det körs lokalt. En AOT-app har följande skillnader från en JIT-kompilerad app:

  • Funktioner som inte är kompatibla med intern AOT inaktiveras och utlöser undantag vid körning.
  • En källanalys har aktiverats för att markera kod som inte är kompatibel med intern AOT. Vid publiceringen analyseras hela appen, inklusive NuGet-paket, för kompatibilitet igen.

Intern AOT-analys innehåller all appkod och de bibliotek som appen är beroende av. Granska interna AOT-varningar och vidta korrigerande åtgärder. Det är en bra idé att publicera appar ofta för att upptäcka problem tidigt i utvecklingslivscykeln.

I .NET 8 stöds intern AOT av följande ASP.NET Core-apptyper:

  • minimala API:er – För mer information, se avsnittet "Webb-API (native AOT) mall " senare i den här artikeln.
  • gRPC – Mer information finns i gRPC och Native AOT.
  • Arbetstjänster – Mer information finns i AOT i Arbetstjänstmallar.

Mallen för Web API (Native AOT)

Mallen ASP.NET Core Web API (Native AOT) (kortnamn webapiaot) skapar ett projekt med AOT aktiverat. Mallen skiljer sig från webb-API projektmall på följande sätt:

  • Använder endast minimala API:er eftersom MVC ännu inte är kompatibelt med intern AOT.
  • Använder CreateSlimBuilder()-API:et för att säkerställa att endast de viktigaste funktionerna är aktiverade som standard, vilket minimerar appens distribuerade storlek.
  • Är konfigurerad för att lyssna endast på HTTP eftersom HTTPS-trafik ofta hanteras av en ingresstjänst i molnbaserade distributioner.
  • Innehåller inte någon startprofil för körning under IIS eller IIS Express.
  • Skapar en .http fil konfigurerad med HTTP-exempelbegäranden som kan skickas till appens slutpunkter.
  • Innehåller ett exempel Todo API i stället för väderprognosexemplet.
  • Lägger till PublishAot i projektfilen, som visades tidigare i denna artikel.
  • Aktiverar JSON-serialiserarens källgeneratorer. Källgeneratorn används för att generera serialiseringskod vid byggtiden, vilket krävs för intern AOT-kompilering.

Ändringar för att stödja källgenerering

I följande exempel visas koden som lagts till i Program.cs-filen för att stödja JSON-serialiseringskällans generering:

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

Utan den här extra koden använder System.Text.Json reflektion för att serialisera och deserialisera JSON. Reflektion stöds inte i Native AOT.

Mer information finns i:

Ändringar i launchSettings.json

Den launchSettings.json fil som skapats av mallen Web API (Native AOT) har iisSettings-avsnittet och IIS Express profilen borttagen:

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

Metoden CreateSlimBuilder

Mallen använder metoden CreateSlimBuilder() i stället för metoden 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
{

}

Metoden CreateSlimBuilder initierar WebApplicationBuilder med de minsta ASP.NET Core-funktioner som krävs för att köra en app.

Som tidigare nämnts innehåller metoden CreateSlimBuilder inte stöd för HTTPS eller HTTP/3. Dessa protokoll krävs vanligtvis inte för appar som körs bakom en TLS-avslutningsproxy. Se till exempel TLS-terminering och slutpunkt till slutpunkt kommunikation med TLS med Application Gateway. HTTPS kan aktiveras genom att anropa builder. WebHost.UseKestrelHttpsConfiguration HTTP/3 kan aktiveras genom att anropa builder. WebHost.UseQuic.

CreateSlimBuilder jämfört med CreateBuilder

Metoden CreateSlimBuilder stöder inte följande funktioner som stöds av metoden CreateBuilder:

Metoden CreateSlimBuilder innehåller följande funktioner som behövs för en effektiv utvecklingsupplevelse:

  • JSON-filkonfiguration för appsettings.json och appsettings.{EnvironmentName}.json.
  • Konfiguration av användarhemligheter.
  • Konsolloggning.
  • Loggningskonfiguration.

För en byggare som utelämnar tidigare funktioner, se Metoden CreateEmptyBuilder.

Att inkludera minimala funktioner har fördelar för optimering såväl som för AOT. Mer information finns i Trimma fristående distributioner och körbara filer.

Mer detaljerad information finns i Jämföra WebApplication.CreateBuilder med CreateSlimBuilder

Källgeneratorer

Eftersom oanvänd kod trimmas under publiceringen för inbyggd AOT kan appen inte använda obegränsade reflektioner vid körning. Programgenererare används för att skapa kod som eliminerar behovet av reflektion. I vissa fall producerar källgeneratorer kod optimerad för AOT även när en generator inte krävs.

Om du vill visa källkoden som genereras lägger du till egenskapen EmitCompilerGeneratedFiles i en apps .csproj fil, enligt följande exempel:

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

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

</Project>

Kör kommandot dotnet build för att se den genererade koden. Utdata innehåller en obj/Debug/net8.0/generated/ katalog som innehåller alla genererade filer för projektet.

Kommandot dotnet publish kompilerar också källfilerna och genererar filer som kompileras. Dessutom skickar dotnet publish de genererade sammansättningarna till en intern IL-kompilator. IL-kompilatorn producerar den inbyggda körbara filen. Den nativa körbara filen innehåller den nativa maskinkoden.

Bibliotek och intern AOT

Många av de populära bibliotek som används i ASP.NET Core-projekt har för närvarande vissa kompatibilitetsproblem när de används i ett projekt som riktar sig till intern AOT, till exempel:

  • Använd reflektion för att inspektera och identifiera typer.
  • Villkorlig inläsning av bibliotek vid körning.
  • Generera kod i farten för att implementera funktioner.

Bibliotek som använder dessa dynamiska funktioner måste uppdateras för att fungera med intern AOT. De kan uppdateras med hjälp av verktyg som Roslyn-källgeneratorer.

Biblioteksförfattare som hoppas kunna stödja native AOT uppmuntras att:

Minimala API:er och JSON-nyttolaster

Det minimala API-ramverket är optimerat för att ta emot och returnera JSON-nyttolaster med hjälp av System.Text.Json. System.Text.Json:

Alla typer som överförs som en del av HTTP-innehållet eller som returneras från begärandedelegater i appar med minimala API:er måste konfigureras med en JsonSerializerContext som registreras via ASP.NET Cores beroendeinmatning.

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
{

}

I föregående markerade kod:

En parameter på ombudet som inte är bunden till brödtexten och som inte behöver vara serialiserbar. Till exempel en frågesträngsparameter som är en omfattande objekttyp och implementerar IParsable<T>.

public class Todo
{
    public int Id { get; set; }
    public string? Title { get; set; }
    public DateOnly? DueBy { get; set; }
    public bool IsComplete { get; set; }
}

static class TodoGenerator
{
    private static readonly (string[] Prefixes, string[] Suffixes)[] _parts = new[]
        {
            (new[] { "Walk the", "Feed the" }, new[] { "dog", "cat", "goat" }),
            (new[] { "Do the", "Put away the" }, new[] { "groceries", "dishes", "laundry" }),
            (new[] { "Clean the" }, new[] { "bathroom", "pool", "blinds", "car" })
        };
    // Remaining code omitted for brevity.

Kända problem

Se i det här GitHub-ärendet för att rapportera eller granska problem med inbyggt AOT-stöd i ASP.NET Core.

Se även