Sdílet prostřednictvím


podpora ASP.NET Core pro nativní AOT

ASP.NET Core 8.0 zavádí podporu nativního rozhraní .NET předem (AOT).

Proč používat nativní AOT s ASP.NET Core

Publikování a nasazení nativní aplikace AOT nabízí následující výhody:

  • Minimalizované nároky na disk: Při publikování pomocí nativní AOT se vytvoří jeden spustitelný soubor obsahující pouze kód z externích závislostí, které jsou potřeba pro podporu programu. Zmenšená velikost spustitelného souboru může vést k:
    • Menší image kontejnerů, například ve scénářích kontejnerizovaného nasazení.
    • Zkrátil se čas nasazení z menších imagí.
  • Kratší doba spuštění: Nativní aplikace AOT můžou zobrazovat kratší dobu spuštění, což znamená
    • Aplikace je připravená k rychlejším žádostem o služby.
    • Vylepšené nasazení, kdy orchestrátory kontejnerů potřebují spravovat přechod z jedné verze aplikace na jinou.
  • Nižší poptávka po paměti: Nativní aplikace AOT můžou mít nižší nároky na paměť v závislosti na práci, kterou aplikace provádí. Snížení spotřeby paměti může vést k vyšší hustotě nasazení a lepší škálovatelnosti.

Aplikace šablony se spustila v našem testovacím prostředí pro srovnávací testy za účelem porovnání výkonu publikované aplikace AOT, oříznuté aplikace modulu runtime a neopakované aplikace modulu runtime. Následující graf ukazuje výsledky srovnávacího testu:

Chart showing comparison of application size, memory use, and startup time metrics of an AOT published app, a runtime app that is trimmed, and an untrimmed runtime app.

Předchozí graf ukazuje, že nativní AOT má nižší velikost aplikace, využití paměti a čas spuštění.

ASP.NET Core a nativní kompatibilita AOT

Ne všechny funkce v ASP.NET Core jsou aktuálně kompatibilní s nativní AOT. Následující tabulka shrnuje kompatibilitu funkcí ASP.NET Core s nativní AOT:

Funkce Plně podporovaná Částečně podporováno Nepodporuje se
gRPC Plně podporovaná
Minimální rozhraní API Částečně podporovaná
MVC Nepodporováno
Blazor Server Nepodporováno
SignalR Nepodporováno
Ověřování JWT Plně podporovaná
Jiné ověřování Nepodporováno
CORS Plně podporovaná
Kontroly stavu Plně podporovaná
HttpLogging Plně podporovaná
Lokalizace Plně podporovaná
Výstup Ukládání do mezipaměti Plně podporovaná
RateLimiting Plně podporovaná
RequestDecompression Plně podporovaná
Odpověď Ukládání do mezipaměti Plně podporovaná
ResponseCompression Plně podporovaná
Přepsat Plně podporovaná
Přednáška Nepodporováno
Spa Nepodporováno
Statické soubory Plně podporovaná
WebSockets Plně podporovaná

Další informace o omezeních najdete tady:

Při přechodu na nativní model nasazení AOT je důležité důkladně otestovat aplikaci. Nasazená aplikace AOT by se měla testovat, aby ověřila, jestli nedošlo ke změně funkčnosti z nezkompilované a kompilované aplikace JIT. Při vytváření aplikace zkontrolujte a opravte upozornění AOT. Aplikace, která během publikování vydává upozornění AOT, nemusí správně fungovat. Pokud nejsou v době publikování vydána žádná upozornění AOT, publikovaná aplikace AOT by měla fungovat stejně jako nekompilovaná a zkompilovaná aplikace JIT.

Nativní publikování AOT

Nativní funkce AOT je povolena s PublishAot vlastností MSBuild. Následující příklad ukazuje, jak povolit nativní AOT v souboru projektu:

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

Toto nastavení umožňuje nativní kompilaci AOT během publikování a umožňuje analýzu dynamického použití kódu během sestavování a úprav. Projekt, který používá nativní publikování AOT, používá kompilaci JIT při místním spuštění. Aplikace AOT má následující rozdíly od zkompilované aplikace JIT:

  • Funkce, které nejsou kompatibilní s nativní technologií AOT, jsou zakázané a vyvolají výjimky za běhu.
  • Zdrojový analyzátor umožňuje zvýraznit kód, který není kompatibilní s nativní AOT. V době publikování se znovu analyzuje celá aplikace, včetně balíčků NuGet, z důvodu zajištění kompatibility.

Nativní analýza AOT zahrnuje veškerý kód aplikace a knihovny, na které aplikace závisí. Zkontrolujte nativní upozornění AOT a proveďte opravné kroky. Je vhodné publikovat aplikace často, aby se v rané fázi životního cyklu vývoje objevily problémy.

V .NET 8 podporuje nativní AOT následující typy aplikací ASP.NET Core:

  • minimální rozhraní API – Další informace najdete v části Šablony webového rozhraní API (Nativní AOT) dále v tomto článku.
  • gRPC – Další informace najdete v tématu gRPC a nativní AOT.
  • Služby pracovních procesů – Další informace najdete v tématu AOT v šablonách pracovních služeb.

Šablona webového rozhraní API (nativní AOT)

Šablona ASP.NET Základní webové rozhraní API (nativní AOT) (krátký název webapiaot) vytvoří projekt s povolenou službou AOT. Šablona se liší od šablony projektu webového rozhraní API následujícími způsoby:

  • Používá jenom minimální rozhraní API, protože MVC ještě není kompatibilní s nativní AOT.
  • CreateSlimBuilder() Pomocí rozhraní API zajistíte, že jsou ve výchozím nastavení povolené jenom základní funkce, což minimalizuje nasazenou velikost aplikace.
  • Je nakonfigurovaná tak, aby naslouchala jenom protokolu HTTP, protože provoz HTTPS obvykle zpracovává služba příchozího přenosu dat v nasazeních nativních pro cloud.
  • Nezahrnuje spouštěcí profil pro spuštění ve službě IIS nebo IIS Express.
  • .http Vytvoří soubor nakonfigurovaný s ukázkovými požadavky HTTP, které se dají odeslat do koncových bodů aplikace.
  • Obsahuje ukázkové Todo rozhraní API místo vzorku předpovědi počasí.
  • Přidá PublishAot do souboru projektu, jak je znázorněno výše v tomto článku.
  • JSPovolí generátory zdroje serializátoru ON. Zdrojový generátor se používá ke generování kódu serializace v době sestavení, což je vyžadováno pro nativní kompilaci AOT.

Změny pro podporu generování zdrojů

Následující příklad ukazuje kód přidaný do Program.cs souboru pro podporu JSgenerování zdroje serializace ON:

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

Bez tohoto přidaného kódu System.Text.Json používá reflexi k serializaci a deserializaci JSON. Reflexe se v nativní AOT nepodporuje.

Další informace naleznete v tématu:

Změny v launchSettings.json

Soubor launchSettings.json vytvořený šablonou webového rozhraní API (Native AOT) obsahuje iisSettings oddíl a IIS Express profil se odebral:

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

Metoda CreateSlimBuilder

Šablona místo metody používá CreateSlimBuilder() metodu 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
{

}

Metoda CreateSlimBuilder inicializuje WebApplicationBuilder minimální ASP.NET core funkce potřebné ke spuštění aplikace.

Jak jsme uvedli dříve, CreateSlimBuilder metoda nezahrnuje podporu protokolu HTTPS nebo HTTP/3. Tyto protokoly se obvykle nevyžadují pro aplikace, které běží za proxy ukončením protokolu TLS. Podívejte se například na ukončení protokolu TLS a ukončení protokolu TLS se službou Application Gateway. HTTPS je možné povolit voláním tvůrce. WebHost.UseKestrelHttpsConfiguration HTTP/3 je možné povolit voláním tvůrce. WebHost.UseQuic.

CreateSlimBuilder versus CreateBuilder

Metoda CreateSlimBuilder nepodporuje následující funkce podporované metodou CreateBuilder :

Tato CreateSlimBuilder metoda obsahuje následující funkce potřebné k efektivnímu vývojovému prostředí:

  • JSKonfigurace souboru ON pro appsettings.json a appsettings.{EnvironmentName}.json.
  • Konfigurace tajných kódů uživatelů
  • Protokolování konzoly.
  • Konfigurace protokolování

Tvůrce, který vynechá předchozí funkce, naleznete v části MetodaCreateEmptyBuilder.

Zahrnutí minimálních funkcí má výhody pro oříznutí a také AOT. Další informace najdete v tématu Oříznutí samostatných nasazení a spustitelných souborů.

Podrobnější informace najdete v tématu Porovnání s WebApplication.CreateBuilderCreateSlimBuilder

Generátory zdrojů

Vzhledem k tomu, že se při publikování nativní AOT oříznou nepoužitý kód, aplikace nemůže za běhu používat nevázané reflexe. Generátory zdrojů se používají k vytvoření kódu, který zabraňuje nutnosti reflexe. V některých případech zdrojové generátory vytvářejí kód optimalizovaný pro AOT i v případě, že generátor není nutný.

Pokud chcete zobrazit zdrojový kód, který se vygeneruje, přidejte EmitCompilerGeneratedFiles vlastnost do souboru aplikace .csproj , jak je znázorněno v následujícím příkladu:

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

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

</Project>

Spuštěním dotnet build příkazu zobrazte vygenerovaný kód. Výstup obsahuje obj/Debug/net8.0/generated/ adresář, který obsahuje všechny vygenerované soubory projektu.

Příkaz dotnet publish také zkompiluje zdrojové soubory a generuje kompilované soubory. Kromě toho dotnet publish předá vygenerovaná sestavení nativnímu kompilátoru IL. Kompilátor IL vytvoří nativní spustitelný soubor. Nativní spustitelný soubor obsahuje nativní kód počítače.

Knihovny a nativní AOT

Mnoho oblíbených knihoven používaných v projektech ASP.NET Core má v současné době problémy s kompatibilitou při použití v projektu, který cílí na nativní AOT, například:

  • Použití reflexe ke kontrole a zjišťování typů.
  • Podmíněné načítání knihoven za běhu
  • Generování kódu za běhu pro implementaci funkcí.

Knihovny používající tyto dynamické funkce je potřeba aktualizovat, aby fungovaly s nativní AOT. Dají se aktualizovat pomocí nástrojů, jako jsou generátory zdrojů Roslyn.

Autoři knihoven, kteří chtějí podporovat nativní AOT, se doporučuje:

Minimální rozhraní API a JSdatová část ON

Minimální rozhraní API je optimalizované pro příjem a vracení JSdatových částí ON pomocí System.Text.Json. System.Text.Json:

  • Ukládá požadavky na kompatibilitu pro JSON a Native AOT.
  • Vyžaduje použití zdrojového generátoruSystem.Text.Json.

Všechny typy přenášené jako součást těla HTTP nebo vrácené delegáty požadavků v aplikacích s minimálními rozhraními API musí být nakonfigurovány na JsonSerializerContext zaregistrované prostřednictvím injektáže závislostí 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
{

}

V předchozím zvýrazněném kódu:

Parametr delegáta, který není vázán na tělo a nemusí být serializovatelný. Například parametr řetězce dotazu, který je bohatým typem objektu a implementuje 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.

Známé problémy

Podívejte se na tento problém Na GitHubu a nahlašte nebo zkontrolujte problémy s nativní podporou AOT v ASP.NET Core.

Viz také