Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Autor: Mitch Denny
Aby zapoznać się ze wskazówkami dotyczącymi natywnej kompilacji AOT, które dodają lub zastępują wskazówki zawarte w tym artykule, zobacz Blazor WebAssembly.
Dlaczego warto używać natywnej AOT z platformą ASP.NET Core
Publikowanie i wdrażanie natywnej aplikacji AOT zapewnia następujące korzyści:
-
Zminimalizowane zużycie dysku: podczas publikowania przy użyciu natywnej funkcji AOT jest tworzony pojedynczy plik wykonywalny zawierający tylko kod z zależności zewnętrznych, które są potrzebne do obsługi programu. Zmniejszony rozmiar pliku wykonywalnego może prowadzić do:
- Mniejsze obrazy kontenerów, na przykład w scenariuszach wdrażania konteneryzowanego.
- Skrócony czas wdrażania dzięki mniejszym obrazom.
-
Skrócony czas uruchamiania: natywne aplikacje AOT mogą pokazywać skrócone czasy uruchamiania, co oznacza
- Aplikacja jest gotowa do szybszego obsługi żądań.
- Ulepszone wdrożenie, w którym koordynatorzy kontenerów muszą zarządzać przejściem z jednej wersji aplikacji do innej.
- Mniejsze zapotrzebowanie na pamięć: natywne aplikacje AOT mogą mieć mniejsze zapotrzebowanie na pamięć w zależności od pracy wykonywanej przez aplikację. Zmniejszenie zużycia pamięci może prowadzić do większej gęstości wdrożenia i zwiększenia skalowalności.
Aplikacja szablonu została uruchomiona w naszym laboratorium porównawczym, aby porównać wydajność aplikacji opublikowanej w trybie AOT, aplikacji wykonanej w przyciętym środowisku uruchomieniowym i aplikacji wykonanej w nieprzyciętym środowisku uruchomieniowym. Na poniższym wykresie przedstawiono wyniki testów porównawczych:
Na poprzednim wykresie pokazano, że natywna usługa AOT ma mniejszy rozmiar aplikacji, użycie pamięci i czas uruchamiania.
Kompatybilność ASP.NET Core i Native AOT
Nie wszystkie funkcje w systemie ASP.NET Core są obecnie zgodne z natywną funkcją AOT. Poniższa tabela zawiera podsumowanie zgodności funkcji ASP.NET Core z natywną funkcją AOT:
Funkcja | W pełni obsługiwane | Częściowo wspierane | Nie jest obsługiwany |
---|---|---|---|
gRPC | W pełni obsługiwane | ||
Minimalne API | Częściowo obsługiwane | ||
MVC | Nieobsługiwane | ||
Blazor Server | Nieobsługiwane | ||
SignalR | Częściowo obsługiwane | ||
Uwierzytelnianie JWT | W pełni obsługiwane | ||
Inne uwierzytelnianie | Nieobsługiwane | ||
CORS (Cross-Origin Resource Sharing) | W pełni obsługiwane | ||
Kontrole kondycji | W pełni obsługiwane | ||
Logowanie HTTP | W pełni obsługiwane | ||
Lokalizacja | W pełni obsługiwane | ||
OutputCaching | W pełni obsługiwane | ||
Ograniczanie częstotliwości | W pełni obsługiwane | ||
Żądanie dekompresji | W pełni obsługiwane | ||
BuforowanieOdpowiedzi | W pełni obsługiwane | ||
Kompresja odpowiedzi | W pełni obsługiwane | ||
Przepisać | W pełni obsługiwane | ||
Sesja | Nieobsługiwane | ||
Uzdrowisko | Nieobsługiwane | ||
StaticFiles | W pełni obsługiwane | ||
WebSocket | W pełni obsługiwane |
Aby uzyskać więcej informacji na temat ograniczeń, zobacz:
- Ograniczenia wdrożenia natywnej usługi AOT
- Wprowadzenie do ostrzeżeń AOT
- Znane niekompatybilności przycinania
- Wprowadzenie do ostrzeżeń dotyczących przycinania
- Problem z usługą GitHub dotnet/core #8288
Ważne jest, aby dokładnie przetestować aplikację podczas przechodzenia do natywnego modelu wdrażania AOT. Aplikacja AOT wdrożona powinna zostać przetestowana w celu sprawdzenia, czy funkcjonalność pozostała niezmieniona w porównaniu do nietrimowanej i skompilowanej za pomocą JIT aplikacji. Podczas kompilowania aplikacji przejrzyj i popraw ostrzeżenia dotyczące AOT. Aplikacja, która wystawia ostrzeżenia AOT podczas publikowania, może nie działać poprawnie. Jeśli w czasie publikowania nie zostaną wydane żadne ostrzeżenia dotyczące funkcji AOT, opublikowana aplikacja AOT powinna działać tak samo jak aplikacja nieskrócona i skompilowana za pomocą JIT.
Publikowanie natywne AOT
Natywna funkcja AOT jest włączona z właściwością PublishAot
MSBuild. W poniższym przykładzie pokazano, jak włączyć natywną funkcję AOT w pliku projektu:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
To ustawienie umożliwia natywną kompilację AOT podczas publikowania i umożliwia dynamiczną analizę użycia kodu podczas kompilacji i edycji. Projekt korzystający z natywnego publikowania AOT używa kompilacji JIT podczas uruchamiania lokalnego. Aplikacja AOT ma następujące różnice w porównaniu z aplikacją skompilowana w trybie JIT:
- Cechy, które nie są zgodne z natywnym AOT, są wyłączane i zgłaszają wyjątki w czasie działania programu.
- Analizator źródła został włączony, aby wyróżnić kod, który nie jest zgodny z Native AOT. W czasie publikowania cała aplikacja, w tym pakiety NuGet, jest ponownie analizowana pod kątem zgodności.
Natywna analiza AOT obejmuje cały kod aplikacji i biblioteki, od których zależy aplikacja. Przejrzyj ostrzeżenia dotyczące natywnej usługi AOT i wykonaj kroki naprawcze. Dobrym pomysłem jest częste publikowanie aplikacji w celu wykrycia problemów na wczesnym etapie cyklu projektowania.
Na platformie .NET 8 natywna funkcja AOT jest obsługiwana przez następujące typy aplikacji ASP.NET Core:
- minimalne API — aby uzyskać więcej informacji, zobacz szablon Web API (Natywne AOT) w dalszej części artykułu.
- gRPC — aby uzyskać więcej informacji, zobacz gRPC i Native AOT.
- Usługi robocze — aby uzyskać więcej informacji, zobacz AOT w szablonach usług roboczych.
Szablon interfejsu API sieci Web (natywne AOT)
Szablon ASP.NET Core Web API (Native AOT) (krótkie oznaczenie webapiaot
) tworzy projekt z włączoną funkcją AOT. Szablon różni się od szablonu projektu Web API w następujący sposób:
- Używa tylko minimalnych interfejsów API, ponieważ MVC nie jest jeszcze zgodne z natywnym AOT.
- Używa interfejsu CreateSlimBuilder() API, aby upewnić się, że tylko podstawowe funkcje są domyślnie włączone, minimalizując rozmiar wdrożonej aplikacji.
- Jest skonfigurowany do nasłuchiwania tylko w protokole HTTP, ponieważ ruch HTTPS jest często obsługiwany przez usługę ruchu przychodzącego we wdrożeniach natywnych dla chmury.
- Nie zawiera profilu uruchamiania do działania w środowiskach IIS lub IIS Express.
-
.http
Tworzy plik skonfigurowany przy użyciu przykładowych żądań HTTP, które można wysyłać do punktów końcowych aplikacji. - Zawiera przykładowy interfejs API
Todo
zamiast przykładowej prognozy pogody. - Dodaje
PublishAot
do pliku projektu, jak pokazano wcześniej w tym artykule. - Włącza generatory źródłowe serializatora JSON. Generator źródła służy do generowania kodu serializacji w czasie kompilacji, który jest wymagany do kompilacji natywnej AOT.
Zmiany w zakresie obsługi generowania kodu źródłowego
W poniższym przykładzie pokazano kod dodany do Program.cs
pliku w celu obsługi generowania źródła serializacji JSON:
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 tego dodanego kodu System.Text.Json
używa refleksji w celu serializacji i deserializacji JSON. Refleksja nie jest obsługiwana w natywnej AOT.
Aby uzyskać więcej informacji, zobacz:
Zmiany do launchSettings.json
Plik launchSettings.json
utworzony przez szablon Web API (natywny AOT) ma usuniętą sekcję iisSettings
oraz profil IIS Express
.
{
"$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
Szablon używa CreateSlimBuilder() metody zamiast CreateBuilder() metody .
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
inicjuje WebApplicationBuilder z minimalnym zestawem funkcji ASP.NET Core niezbędnymi do uruchomienia aplikacji.
Jak wspomniano wcześniej, CreateSlimBuilder
metoda nie obejmuje obsługi protokołu HTTPS lub HTTP/3. Te protokoły zazwyczaj nie są wymagane w przypadku aplikacji uruchamianych za serwerem proxy zakończenia protokołu TLS. Zobacz na przykład terminację TLS i szyfrowanie TLS typu end-to-end za pomocą usługi Application Gateway. Protokół HTTPS można włączyć, wywołując konstruktora builder.WebHost.UseKestrelHttpsConfiguration. Protokół HTTP/3 można włączyć, wywołując konstruktora builder.WebHost.UseQuic.
Klasa CreateSlimBuilder
a klasa CreateBuilder
Metoda CreateSlimBuilder
nie obsługuje następujących funkcji obsługiwanych przez metodę CreateBuilder
:
- Hosting zgromadzeń startupowych
- UseStartup
- Następujący dostawcy logowania:
- Funkcje hostingu internetowego:
- Kestrel konfiguracja
- Ograniczenia regex i alfa używane w routingu
Metoda CreateSlimBuilder
zawiera następujące funkcje potrzebne do wydajnego środowiska programistycznego:
- Konfiguracja pliku JSON dla elementów
appsettings.json
iappsettings.{EnvironmentName}.json
. - Konfiguracja tajnych danych użytkownika.
- Logowanie konsoli.
- Konfiguracja rejestrowania.
Aby zapoznać się z narzędziem budowania, które pomija wcześniejsze funkcjonalności, zobacz Metoda CreateEmptyBuilder
.
Uwzględnienie minimalnych funkcji przynosi korzyści dla przycinania oraz AOT. Aby uzyskać więcej informacji, zobacz Przycinanie samodzielnych wdrożeń i plików wykonywalnych.
Aby uzyskać bardziej szczegółowe informacje, zobacz Porównanie WebApplication.CreateBuilder
z CreateSlimBuilder
Generatory źródeł
Ponieważ nieużywany kod jest usuwany podczas publikowania w kontekście natywnego AOT, aplikacja nie może używać nieograniczonego odbicia w czasie wykonywania. Generatory źródeł są używane do tworzenia kodu, który pozwala uniknąć konieczności odbicia. W niektórych przypadkach generatory źródłowe generują kod zoptymalizowany pod kątem AOT nawet wtedy, gdy generator nie jest wymagany.
Aby wyświetlić wygenerowany kod źródłowy, dodaj właściwość EmitCompilerGeneratedFiles
do pliku .csproj
aplikacji, jak pokazano w poniższym przykładzie.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Other properties omitted for brevity -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
</Project>
Uruchom polecenie , dotnet build
aby wyświetlić wygenerowany kod. Dane wyjściowe zawierają obj/Debug/net8.0/generated/
katalog zawierający wszystkie wygenerowane pliki dla projektu.
Polecenie dotnet publish
kompiluje również pliki źródłowe i generuje skompilowane pliki. Ponadto dotnet publish
przekazuje wygenerowane zestawy do natywnego kompilatora IL. Kompilator IL tworzy natywny plik wykonywalny. Natywny plik wykonywalny zawiera natywny kod maszyny.
Biblioteki i natywna usługa AOT
Wiele popularnych bibliotek używanych w projektach ASP.NET Core ma obecnie pewne problemy ze zgodnością w przypadku użycia w projekcie przeznaczonym dla natywnej funkcji AOT, takich jak:
- Używanie odbicia do sprawdzania i odnajdywania typów.
- Warunkowe ładowanie bibliotek w czasie wykonywania.
- Generowanie kodu na bieżąco w celu zaimplementowania funkcji.
Biblioteki korzystające z tych funkcji dynamicznych należy zaktualizować w celu pracy z natywną usługą AOT. Można je aktualizować przy użyciu narzędzi, takich jak generatory źródeł Roslyn.
Autorzy bibliotek, którzy mają nadzieję obsługiwać natywne AOT, są zachęcani do:
- Przeczytaj o wymaganiach dotyczących zgodności z natywnym AOT.
- Przygotuj bibliotekę do przycinania.
Minimalne interfejsy API i ładunki JSON
Minimalna struktura interfejsu API jest zoptymalizowana pod kątem odbierania i zwracania ładunków JSON przy użyciu polecenia System.Text.Json.
System.Text.Json
:
- Nakłada wymagania dotyczące zgodności dla formatu JSON i natywnego AOT.
- Wymaga użycia generatora źródeł
System.Text.Json
.
Wszystkie typy przesyłane jako część treści HTTP lub zwracane z delegatów żądań w aplikacjach minimalnych interfejsów API muszą być skonfigurowane na obiekcie JsonSerializerContext , który jest zarejestrowany za pośrednictwem wstrzykiwania zależności 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
{
}
W poprzednim wyróżnionym kodzie:
- Kontekst serializatora JSON jest zarejestrowany w kontenerze DI. Aby uzyskać więcej informacji, zobacz:
- Element niestandardowy
JsonSerializerContext
jest oznaczony adnotacją z atrybutem[JsonSerializable]
, która umożliwia włączenie kodu serializatora JSON wygenerowanego przez źródło dla typuToDo
.
Parametr delegata, który nie jest powiązany z treścią i nie musi być serializowalny. Na przykład parametr ciągu zapytania, który jest bogatym typem obiektu i implementuje element 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.
Znane problemy
Zobacz to zadanie GitHub, aby zgłosić lub przejrzeć problemy z natywną obsługą Native AOT w ASP.NET Core.
Zobacz też
- Samouczek: publikowanie aplikacji ASP.NET Core przy użyciu natywnej usługi AOT
- Wdrożenie natywnej usługi AOT
- Optymalizowanie wdrożeń usługi AOT
- Generator źródła wiązania konfiguracji
- Korzystanie z generatora źródła powiązania konfiguracji
- Minimalny szablon kompilacji AOT API
-
Porównanie
WebApplication.CreateBuilder
zCreateSlimBuilder
- Eksplorowanie nowego minimalnego generatora źródła interfejsu API
- Zastępowanie wywołań metod interceptorami
-
Za
[LogProperties]
i nowy generator źródeł rejestrowania telemetrii
Platforma .NET 8 wprowadza obsługę natywnej kompilacji .NET wykonywanej z wyprzedzeniem (AOT).
Dlaczego warto używać natywnej AOT z platformą ASP.NET Core
Publikowanie i wdrażanie natywnej aplikacji AOT zapewnia następujące korzyści:
-
Zminimalizowane zużycie dysku: podczas publikowania przy użyciu natywnej funkcji AOT jest tworzony pojedynczy plik wykonywalny zawierający tylko kod z zależności zewnętrznych, które są potrzebne do obsługi programu. Zmniejszony rozmiar pliku wykonywalnego może prowadzić do:
- Mniejsze obrazy kontenerów, na przykład w scenariuszach wdrażania konteneryzowanego.
- Skrócony czas wdrażania dzięki mniejszym obrazom.
-
Skrócony czas uruchamiania: natywne aplikacje AOT mogą pokazywać skrócone czasy uruchamiania, co oznacza
- Aplikacja jest gotowa do szybszego obsługi żądań.
- Ulepszone wdrożenie, w którym koordynatorzy kontenerów muszą zarządzać przejściem z jednej wersji aplikacji do innej.
- Mniejsze zapotrzebowanie na pamięć: natywne aplikacje AOT mogą mieć mniejsze zapotrzebowanie na pamięć w zależności od pracy wykonywanej przez aplikację. Zmniejszenie zużycia pamięci może prowadzić do większej gęstości wdrożenia i zwiększenia skalowalności.
Aplikacja szablonu została uruchomiona w naszym laboratorium porównawczym, aby porównać wydajność aplikacji opublikowanej w trybie AOT, aplikacji wykonanej w przyciętym środowisku uruchomieniowym i aplikacji wykonanej w nieprzyciętym środowisku uruchomieniowym. Na poniższym wykresie przedstawiono wyniki testów porównawczych:
Na poprzednim wykresie pokazano, że natywna usługa AOT ma mniejszy rozmiar aplikacji, użycie pamięci i czas uruchamiania.
Kompatybilność ASP.NET Core i Native AOT
Nie wszystkie funkcje w systemie ASP.NET Core są obecnie zgodne z natywną funkcją AOT. Poniższa tabela zawiera podsumowanie zgodności funkcji ASP.NET Core z natywną funkcją AOT:
Funkcja | W pełni obsługiwane | Częściowo wspierane | Nie jest obsługiwany |
---|---|---|---|
gRPC | W pełni obsługiwane | ||
Minimalne API | Częściowo obsługiwane | ||
MVC | Nieobsługiwane | ||
Blazor Server | Nieobsługiwane | ||
SignalR | Nieobsługiwane | ||
Uwierzytelnianie JWT | W pełni obsługiwane | ||
Inne uwierzytelnianie | Nieobsługiwane | ||
CORS (Cross-Origin Resource Sharing) | W pełni obsługiwane | ||
Kontrole kondycji | W pełni obsługiwane | ||
Logowanie HTTP | W pełni obsługiwane | ||
Lokalizacja | W pełni obsługiwane | ||
OutputCaching | W pełni obsługiwane | ||
Ograniczanie częstotliwości | W pełni obsługiwane | ||
Żądanie dekompresji | W pełni obsługiwane | ||
BuforowanieOdpowiedzi | W pełni obsługiwane | ||
Kompresja odpowiedzi | W pełni obsługiwane | ||
Przepisać | W pełni obsługiwane | ||
Sesja | Nieobsługiwane | ||
Uzdrowisko | Nieobsługiwane | ||
StaticFiles | W pełni obsługiwane | ||
WebSocket | W pełni obsługiwane |
Aby uzyskać więcej informacji na temat ograniczeń, zobacz:
- Ograniczenia wdrożenia natywnej usługi AOT
- Wprowadzenie do ostrzeżeń AOT
- Znane niekompatybilności przycinania
- Wprowadzenie do ostrzeżeń dotyczących przycinania
- Problem z usługą GitHub dotnet/core #8288
Ważne jest, aby dokładnie przetestować aplikację podczas przechodzenia do natywnego modelu wdrażania AOT. Aplikacja AOT wdrożona powinna zostać przetestowana w celu sprawdzenia, czy funkcjonalność pozostała niezmieniona w porównaniu do nietrimowanej i skompilowanej za pomocą JIT aplikacji. Podczas kompilowania aplikacji przejrzyj i popraw ostrzeżenia dotyczące AOT. Aplikacja, która wystawia ostrzeżenia AOT podczas publikowania, może nie działać poprawnie. Jeśli w czasie publikowania nie zostaną wydane żadne ostrzeżenia dotyczące funkcji AOT, opublikowana aplikacja AOT powinna działać tak samo jak aplikacja nieskrócona i skompilowana za pomocą JIT.
Publikowanie natywne AOT
Natywna funkcja AOT jest włączona z właściwością PublishAot
MSBuild. W poniższym przykładzie pokazano, jak włączyć natywną funkcję AOT w pliku projektu:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
To ustawienie umożliwia natywną kompilację AOT podczas publikowania i umożliwia dynamiczną analizę użycia kodu podczas kompilacji i edycji. Projekt korzystający z natywnego publikowania AOT używa kompilacji JIT podczas uruchamiania lokalnego. Aplikacja AOT ma następujące różnice w porównaniu z aplikacją skompilowana w trybie JIT:
- Cechy, które nie są zgodne z natywnym AOT, są wyłączane i zgłaszają wyjątki w czasie działania programu.
- Analizator źródła został włączony, aby wyróżnić kod, który nie jest zgodny z Native AOT. W czasie publikowania cała aplikacja, w tym pakiety NuGet, jest ponownie analizowana pod kątem zgodności.
Natywna analiza AOT obejmuje cały kod aplikacji i biblioteki, od których zależy aplikacja. Przejrzyj ostrzeżenia dotyczące natywnej usługi AOT i wykonaj kroki naprawcze. Dobrym pomysłem jest częste publikowanie aplikacji w celu wykrycia problemów na wczesnym etapie cyklu projektowania.
Na platformie .NET 8 natywna funkcja AOT jest obsługiwana przez następujące typy aplikacji ASP.NET Core:
- minimalne API — aby uzyskać więcej informacji, zobacz szablon Web API (Natywne AOT) w dalszej części artykułu.
- gRPC — aby uzyskać więcej informacji, zobacz gRPC i Native AOT.
- Usługi robocze — aby uzyskać więcej informacji, zobacz AOT w szablonach usług roboczych.
Szablon interfejsu API sieci Web (natywne AOT)
Szablon ASP.NET Core Web API (Native AOT) (krótkie oznaczenie webapiaot
) tworzy projekt z włączoną funkcją AOT. Szablon różni się od szablonu projektu Web API w następujący sposób:
- Używa tylko minimalnych interfejsów API, ponieważ MVC nie jest jeszcze zgodne z natywnym AOT.
- Używa interfejsu CreateSlimBuilder() API, aby upewnić się, że tylko podstawowe funkcje są domyślnie włączone, minimalizując rozmiar wdrożonej aplikacji.
- Jest skonfigurowany do nasłuchiwania tylko w protokole HTTP, ponieważ ruch HTTPS jest często obsługiwany przez usługę ruchu przychodzącego we wdrożeniach natywnych dla chmury.
- Nie zawiera profilu uruchamiania do działania w środowiskach IIS lub IIS Express.
-
.http
Tworzy plik skonfigurowany przy użyciu przykładowych żądań HTTP, które można wysyłać do punktów końcowych aplikacji. - Zawiera przykładowy interfejs API
Todo
zamiast przykładowej prognozy pogody. - Dodaje
PublishAot
do pliku projektu, jak pokazano wcześniej w tym artykule. - Włącza generatory źródłowe serializatora JSON. Generator źródła służy do generowania kodu serializacji w czasie kompilacji, który jest wymagany do kompilacji natywnej AOT.
Zmiany w zakresie obsługi generowania kodu źródłowego
W poniższym przykładzie pokazano kod dodany do Program.cs
pliku w celu obsługi generowania źródła serializacji JSON:
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 tego dodanego kodu System.Text.Json
używa refleksji w celu serializacji i deserializacji JSON. Refleksja nie jest obsługiwana w natywnej AOT.
Aby uzyskać więcej informacji, zobacz:
Zmiany do launchSettings.json
Plik launchSettings.json
utworzony przez szablon Web API (natywny AOT) ma usuniętą sekcję iisSettings
oraz profil IIS Express
.
{
"$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
Szablon używa CreateSlimBuilder() metody zamiast CreateBuilder() metody .
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
inicjuje WebApplicationBuilder z minimalnym zestawem funkcji ASP.NET Core niezbędnymi do uruchomienia aplikacji.
Jak wspomniano wcześniej, CreateSlimBuilder
metoda nie obejmuje obsługi protokołu HTTPS lub HTTP/3. Te protokoły zazwyczaj nie są wymagane w przypadku aplikacji uruchamianych za serwerem proxy zakończenia protokołu TLS. Zobacz na przykład terminację TLS i szyfrowanie TLS typu end-to-end za pomocą usługi Application Gateway. Protokół HTTPS można włączyć, wywołując konstruktora builder.WebHost.UseKestrelHttpsConfiguration. Protokół HTTP/3 można włączyć, wywołując konstruktora builder.WebHost.UseQuic.
Klasa CreateSlimBuilder
a klasa CreateBuilder
Metoda CreateSlimBuilder
nie obsługuje następujących funkcji obsługiwanych przez metodę CreateBuilder
:
- Hosting zgromadzeń startupowych
- UseStartup
- Następujący dostawcy logowania:
- Funkcje hostingu internetowego:
- Kestrel konfiguracja
- Ograniczenia regex i alfa używane w routingu
Metoda CreateSlimBuilder
zawiera następujące funkcje potrzebne do wydajnego środowiska programistycznego:
- Konfiguracja pliku JSON dla elementów
appsettings.json
iappsettings.{EnvironmentName}.json
. - Konfiguracja tajnych danych użytkownika.
- Logowanie konsoli.
- Konfiguracja rejestrowania.
Aby zapoznać się z narzędziem budowania, które pomija wcześniejsze funkcjonalności, zobacz Metoda CreateEmptyBuilder
.
Uwzględnienie minimalnych funkcji przynosi korzyści dla przycinania oraz AOT. Aby uzyskać więcej informacji, zobacz Przycinanie samodzielnych wdrożeń i plików wykonywalnych.
Aby uzyskać bardziej szczegółowe informacje, zobacz Porównanie WebApplication.CreateBuilder
z CreateSlimBuilder
Generatory źródeł
Ponieważ nieużywany kod jest usuwany podczas publikowania w kontekście natywnego AOT, aplikacja nie może używać nieograniczonego odbicia w czasie wykonywania. Generatory źródeł są używane do tworzenia kodu, który pozwala uniknąć konieczności odbicia. W niektórych przypadkach generatory źródłowe generują kod zoptymalizowany pod kątem AOT nawet wtedy, gdy generator nie jest wymagany.
Aby wyświetlić wygenerowany kod źródłowy, dodaj właściwość EmitCompilerGeneratedFiles
do pliku .csproj
aplikacji, jak pokazano w poniższym przykładzie.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Other properties omitted for brevity -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
</Project>
Uruchom polecenie , dotnet build
aby wyświetlić wygenerowany kod. Dane wyjściowe zawierają obj/Debug/net8.0/generated/
katalog zawierający wszystkie wygenerowane pliki dla projektu.
Polecenie dotnet publish
kompiluje również pliki źródłowe i generuje skompilowane pliki. Ponadto dotnet publish
przekazuje wygenerowane zestawy do natywnego kompilatora IL. Kompilator IL tworzy natywny plik wykonywalny. Natywny plik wykonywalny zawiera natywny kod maszyny.
Biblioteki i natywna usługa AOT
Wiele popularnych bibliotek używanych w projektach ASP.NET Core ma obecnie pewne problemy ze zgodnością w przypadku użycia w projekcie przeznaczonym dla natywnej funkcji AOT, takich jak:
- Używanie odbicia do sprawdzania i odnajdywania typów.
- Warunkowe ładowanie bibliotek w czasie wykonywania.
- Generowanie kodu na bieżąco w celu zaimplementowania funkcji.
Biblioteki korzystające z tych funkcji dynamicznych należy zaktualizować w celu pracy z natywną usługą AOT. Można je aktualizować przy użyciu narzędzi, takich jak generatory źródeł Roslyn.
Autorzy bibliotek, którzy mają nadzieję obsługiwać natywne AOT, są zachęcani do:
- Przeczytaj o wymaganiach dotyczących zgodności z natywnym AOT.
- Przygotuj bibliotekę do przycinania.
Minimalne interfejsy API i ładunki JSON
Minimalna struktura interfejsu API jest zoptymalizowana pod kątem odbierania i zwracania ładunków JSON przy użyciu polecenia System.Text.Json.
System.Text.Json
:
- Nakłada wymagania dotyczące zgodności dla formatu JSON i natywnego AOT.
- Wymaga użycia generatora źródeł
System.Text.Json
.
Wszystkie typy przesyłane jako część treści HTTP lub zwracane z delegatów żądań w aplikacjach minimalnych interfejsów API muszą być skonfigurowane na obiekcie JsonSerializerContext , który jest zarejestrowany za pośrednictwem wstrzykiwania zależności 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
{
}
W poprzednim wyróżnionym kodzie:
- Kontekst serializatora JSON jest zarejestrowany w kontenerze DI. Aby uzyskać więcej informacji, zobacz:
- Element niestandardowy
JsonSerializerContext
jest oznaczony adnotacją z atrybutem[JsonSerializable]
, która umożliwia włączenie kodu serializatora JSON wygenerowanego przez źródło dla typuToDo
.
Parametr delegata, który nie jest powiązany z treścią i nie musi być serializowalny. Na przykład parametr ciągu zapytania, który jest bogatym typem obiektu i implementuje element 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.
Znane problemy
Zobacz to zadanie GitHub, aby zgłosić lub przejrzeć problemy z natywną obsługą Native AOT w ASP.NET Core.
Zobacz też
- Samouczek: publikowanie aplikacji ASP.NET Core przy użyciu natywnej usługi AOT
- Wdrożenie natywnej usługi AOT
- Optymalizowanie wdrożeń usługi AOT
- Generator źródła wiązania konfiguracji
- Korzystanie z generatora źródła powiązania konfiguracji
- Minimalny szablon kompilacji AOT API
-
Porównanie
WebApplication.CreateBuilder
zCreateSlimBuilder
- Eksplorowanie nowego minimalnego generatora źródła interfejsu API
- Zastępowanie wywołań metod interceptorami
-
Za
[LogProperties]
i nowy generator źródeł rejestrowania telemetrii