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

Av Mitch Denny

Publicering och distribution av Native Ahead-of-Time (AOT) applikationer i ASP.NET Core erbjuder flera fördelar:

  • Minimerat diskavtryck. När du publicerar en app med inbyggd AOT skapar processen en enda körbar fil. Den körbara filen innehåller endast koden från de externa beroenden som krävs för att stödja appen. Den minskade körbara storleken kan leda till:

    • Mindre containeravbildningar, till exempel i scenarier med containerbaserad distribution.
    • Minskad implementeringstid med mindre bilder.
  • Kortare starttid. Interna AOT-appar kan kräva mindre starttid, vilket möjliggör:

    • Appen för snabbare serviceförfrågningar.
    • Förbättrad distribution, där containerorkestratorerna hanterar övergången från en appversion till en annan.
  • Minskad minnesefterfrågan. Interna AOT-appar kan kräva mindre minne, beroende på vilket arbete som utförs av appen. Minskad minnesförbrukning kan leda till större distributionsdensitet och förbättrad skalbarhet.

Följande diagram visar resultatet av ett benchmarking-test på de olika mallapparna. Benchmark jämför prestanda för en AOT-publicerad app (orange stapel), en trimmad körningsapp (grön stapel) och en otrimmad körningsapp (gul stapel). Testet visade att den interna AOT-appen visar lägre appstorlek, minnesanvändning och starttid.

Diagram som visar en jämförelse av appens storlek, minnesanvändning och starttidsmått. Diagrammet jämför en publicerad intern AOT-app, en trimmad körningsapp och en otrimmad körningsapp.

Den här artikeln beskriver stöd för interna AOT-appar i ASP.NET Core, inklusive en översikt över publicering och distribution.

Vägledning för ASP.NET Core 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.

Granska 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 Partiellt stöd Stöds ej
Blazor Server
CORS (Cross-Origin Resource Sharing) ✔️
gRPC ✔️
Hälsokontroller ✔️
HttpLogging ✔️
JWT-autentisering ✔️
Lokalisering ✔️
Minimala API:er ✔️
MVC
Annan autentisering
OutputCaching ✔️
Hastighetsbegränsning ✔️
BegäranOmDekomprimering ✔️
Svarcachning ✔️
Svarskomprimering ✔️
Skriv om ✔️
Sittning
SignalR ✔️
Brunn
StaticFiles ✔️
WebSockets (En protokoll för realtidskommunikation över webben) ✔️

Mer information om begränsningar finns i:

Verifiera appen på den Native AOT-distributionsmodellen

Det är viktigt att testa en app noggrant när du går över till en intern AOT-distributionsmodell. Testa den AOT-distribuerade appen och bekräfta att funktionen inte har ändrats från den otrimmade JIT-kompilerade (just-in-time) appen.

När du skapar appen granskar och korrigerar du eventuella AOT-varningar. En app som utfärdar AOT-varningar under publiceringen kanske inte fungerar korrekt. Om inga AOT-varningar utfärdas vid publiceringstillfället kan du förvänta dig att den publicerade AOT-appen fungerar på samma sätt som den otrimmade och JIT-kompilerade appen.

Publicera en Native AOT-app (PublishAot)

Aktivera intern AOT för ditt program med hjälp PublishAot av egenskapen MSBuild. I följande exempel visas hur du aktiverar intern AOT i en projektfil:

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

Egenskapen PublishAot möjliggör intern AOT-kompilering under publiceringsprocessen och möjliggör dynamisk kodanvändningsanalys under kompilering och redigering. Ett projekt som använder intern AOT-publicering implementerar 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 programkod 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 och senare stöder följande ASP.NET Core apptyper intern AOT:

Granska mallen för Webb-API (Native AOT)

Mallen ASP.NET Core Web API (Native AOT) (kortnamn webapiaot) skapar ett projekt med AOT aktiverat. Mallen skiljer sig från en vanlig 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 API:et CreateSlimBuilder() 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 endast lyssna på HTTP. HTTPS-trafik hanteras ofta 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 som konfigurerats 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 egenskapen PublishAot i projektfilen enligt beskrivningen tidigare.
  • Aktiverar JSON-serialiserarens källgeneratorer. Källgeneratorn används för att generera serialiseringskod vid byggtiden, vilket krävs för intern AOT-kompilering.

Koduppdateringar för JSON-serialisering (Program.cs)

Koden i Program.cs-filen ändras för att ge stöd för JSON-serialiseringskällans generering.

Följande kodfragment visar ändringarna i koden:

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

Om du inte ändrar koden System.Text.Json använder du reflektion för att serialisera och deserialisera JSON. Reflektion stöds inte i Native AOT.

Mer information finns i:

Kodändringar för startprofil (launchSettings.json)

Mallen Web API (Native AOT) skapar en launchSettings.json fil. Till skillnad från en standardstartfil innehåller den genererade filen inte iisSettings avsnittet eller IIS Express profilen.

Följande kodfragment visar de exkluderade avsnitten (färgade röda):

{
  "$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() anropas för minimala appstandardvärden

Webb-API-mallen (intern AOT) använder CreateSlimBuilder() metoden i stället för CreateBuilder() metoden.

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 vi beskrev tidigare CreateSlimBuilder innehåller metoden 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. Du kan aktivera HTTPS genom att anropa byggaren. WebHost.UseKestrelHttpsConfiguration-metoden eller aktivera HTTP/3 genom att anropa byggverktyget. WebHost.UseQuic.

Jämför CreateSlimBuilder() och CreateBuilder()

Metoden CreateSlimBuilder ger åtkomst till en del av de programfunktioner som är tillgängliga med CreateBuilder metoden. Som vi beskrev tidigare anropar mallen Web API (Native AOT)CreateSlimBuilder för att initiera WebApplicationBuilder, så att byggaren använder de minsta ASP.NET Core funktioner som krävs för att köra appen.

Båda metoderna tillhandahåller de nödvändiga funktionerna för en effektiv utvecklingsupplevelse:

  • Konfiguration för appsettings.json och apparinställningar.{ EnvironmentName}.json filer
  • Konfiguration av användarhemligheter
  • Konsolloggning
  • Loggningskonfiguration

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."

Om du föredrar att använda en byggare som utelämnar alla funktioner kan du läsa metoden WebApplication.CreateEmptyBuilder .

Funktioner som inte är tillgängliga i CreateSlimBuilder

Metoden CreateSlimBuildertillhandahåller inte följande funktioner som är tillgängliga i CreateBuilder:

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

Använd källgeneratorer och undvik reflektion

Under publiceringsprocessen för Native AOT trimmas all oanvänd kod. Därför kan en app inte använda obunden reflektion vid körning. Du kan använda källgeneratorer som producerar kod som undviker behovet av reflektion. I vissa fall är källgeneratorernas utdatakod optimerad för AOT även när en generator inte krävs.

  • Om du vill visa den genererade källkoden lägger du till egenskapen EmitCompilerGeneratedFiles i programprojektets fil (.csproj):

    <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. Kommandot kompilerar källfilerna och genererar de mellanliggande filer som behövs för att köra appen i en utvecklingsmiljö. Utdata innehåller en obj/Debug/<.NET version>/generated/ katalog som innehåller alla genererade filer för projektet.

  • Kör kommandot för att förbereda appen för distribution.dotnet publish Kommandot kompilerar källfilerna och genererar alla filer som krävs för att distribuera appen. Den skickar de genererade sammansättningarna till en intern IL-kompilator, som producerar den inbyggda körbara filen. Den inhemska körbara filen innehåller den inhemska maskinkoden.

Använda bibliotek med inbyggd AOT

Många populära bibliotek som används i ASP.NET Core projekt har för närvarande vissa kompatibilitetsproblem när de införlivas i projekt som är inriktade på intern AOT, till exempel:

  • Använda reflektion för att inspektera och identifiera typer
  • Laddar bibliotek villkorligt under körning
  • Generera kod i farten för att implementera funktioner

Bibliotek som använder dessa dynamiska funktioner kräver uppdateringar för att fungera med intern AOT. Det finns olika verktyg för att tillämpa nödvändiga uppdateringar, till exempel Roslyn-källgeneratorer.

Biblioteksförfattare som hoppas kunna stödja native AOT uppmuntras att granska följande artiklar:

Arbeta med 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.

Alla typer som överförs som en del av HTTP-kroppen eller som returneras från begäransdelegater i appar med Minimal APIs måste konfigureras på en JsonSerializerContext instans. Instansen måste registreras med ASP.NET Core 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
{
}

En parameter i delegeringen som inte är bunden till brödtexten behöver inte vara serialiserbar. En frågesträngsparameter kan till exempel vara en omfattande objekttyp som 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.

Granska kända problem

Information om hur du rapporterar eller granskar problem med internt AOT-stöd i ASP.NET Core finns i GitHub /dotnet/core/issues #8288).

.NET 8 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 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 ✔️ helt stöds
Minimala API:er ✔️ delvis stöds
MVC Stöds inte
Blazor Server Stöds inte
SignalR Stöds inte
JWT-autentisering ✔️ helt stöds
Annan autentisering Stöds inte
CORS (Cross-Origin Resource Sharing) ✔️ helt stöds
Hälsokontroller ✔️ helt stöds
HttpLogging ✔️ helt stöds
Lokalisering ✔️ helt stöds
OutputCaching ✔️ helt stöds
Hastighetsbegränsning ✔️ helt stöds
BegäranOmDekomprimering ✔️ helt stöds
Svarcachning ✔️ helt stöds
Svarskomprimering ✔️ helt stöds
Skriv om ✔️ helt stöds
Sittning Stöds inte
Brunn Stöds inte
StaticFiles ✔️ helt stöds
WebSockets (En protokoll för realtidskommunikation över webben) ✔️ helt 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"
-      }
-    }
  }
}

CreateSlimBuilder metoden

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.
  • Loggning av konsol.
  • 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.

Använda bibliotek med inbyggd AOT

Många populära bibliotek som används i ASP.NET Core projekt har för närvarande vissa kompatibilitetsproblem när de införlivas i projekt som är inriktade på intern AOT, till exempel:

  • Använda reflektion för att inspektera och identifiera typer
  • Laddar bibliotek villkorligt under körning
  • Generera kod i farten för att implementera funktioner

Bibliotek som använder dessa dynamiska funktioner kräver uppdateringar för att fungera med intern AOT. Det finns olika verktyg för att tillämpa nödvändiga uppdateringar, till exempel Roslyn-källgeneratorer.

Biblioteksförfattare som hoppas kunna stödja native AOT uppmuntras att granska följande artiklar:

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