Suporte ASP.NET Core para AOT nativo
Por Mitch Denny
ASP.NET Core 8.0 introduz suporte para de antecipação (AOT) nativo do .NET.
Para obter Blazor WebAssembly orientação de AOT nativa, que adiciona ou substitui a orientação neste artigo, consulte ASP.NET Core Blazor WebAssembly build tools and ahead-of-time (AOT) compilation.
Por que usar AOT nativo com ASP.NET Core
Publicar e implantar um aplicativo AOT nativo oferece os seguintes benefícios:
-
Minimized disk footprint: Ao publicar usando AOT nativo, é produzido um único executável que contém apenas o código das dependências externas necessário para suportar o programa. O tamanho reduzido do executável pode levar a:
- Imagens de contentor mais pequenas, por exemplo, em cenários de implantação em contentores.
- Tempo de implantação reduzido a partir de imagens menores.
-
Tempo de inicialização reduzido: Os aplicativos AOT nativos podem mostrar tempos de inicialização reduzidos, o que significa
- O aplicativo está pronto para atender solicitações mais rapidamente.
- Implantação aprimorada em que os orquestradores de contêineres precisam gerenciar a transição de uma versão do aplicativo para outra.
- Demanda de memória reduzida: Os aplicativos AOT nativos podem ter demandas de memória reduzidas, dependendo do trabalho feito pelo aplicativo. O consumo reduzido de memória pode levar a uma maior densidade de implantação e melhor escalabilidade.
O aplicativo de modelo foi executado em nosso laboratório de benchmarking para comparar o desempenho de um aplicativo publicado pela AOT, um aplicativo de tempo de execução cortado e um aplicativo de tempo de execução não cortado. O gráfico a seguir mostra os resultados do benchmarking:
O gráfico anterior mostra que a AOT nativa tem menor tamanho de aplicativo, uso de memória e tempo de inicialização.
Compatibilidade do ASP.NET Core com AOT nativo
Nem todos os recursos do ASP.NET Core são atualmente compatíveis com a AOT nativa. A tabela a seguir resume a compatibilidade de recursos do ASP.NET Core com o AOT Nativo:
Funcionalidade | Totalmente suportado | Parcialmente suportado | Não suportado |
---|---|---|---|
gRPC | ✔️ Totalmente suportado | ||
APIs mínimas | ✔️ Parcialmente suportado | ||
MVC | Não suportado | ||
Blazor Server | Não suportado | ||
SignalR | ✔️ Parcialmente suportado | ||
Autenticação JWT | ✔️ Totalmente suportado | ||
Outra autenticação | Não suportado | ||
CORS | ✔️ Totalmente suportado | ||
Verificações de saúde | ✔️ Totalmente suportado | ||
HttpLogging | ✔️ Totalmente suportado | ||
Localização | ✔️ Totalmente suportado | ||
OutputCaching | ✔️ Totalmente suportado | ||
Limitação de Taxa | ✔️ Totalmente suportado | ||
PedidoDescompressão | ✔️ ✔️ Totalmente suportado | ||
ResponseCaching | ✔️ Totalmente suportado | ||
CompressãoDeResposta | ✔️ Totalmente suportado | ||
Reescrever | ✔️ Totalmente suportado | ||
Sessão | Não suportado | ||
Termas | Não suportado | ||
Arquivos Estáticos | ✔️ Totalmente suportado | ||
WebSockets | ✔️ Totalmente suportado |
Para obter mais informações sobre limitações, consulte:
- Limitações do de implantação de AOT nativo
- Introdução aos avisos AOT
- Incompatibilidades de corte conhecidas
- Introdução aos avisos de corte
- Problema do GitHub dotnet/core #8288
É importante testar um aplicativo completamente ao mudar para um modelo de implantação AOT nativo. O aplicativo implantado pela AOT deve ser testado para verificar se a funcionalidade não foi alterada do aplicativo não cortado e compilado em JIT. Ao criar o aplicativo, revise e corrija os avisos da AOT. Uma aplicação que emite avisos de AOT durante a publicação pode não funcionar corretamente. Se não forem emitidos avisos de AOT no momento da publicação, a aplicação AOT publicada deverá funcionar da mesma forma que a aplicação não otimizada e compilada em JIT.
Publicação AOT nativa
O Native AOT é habilitado com a propriedade PublishAot
MSBuild. O exemplo a seguir mostra como habilitar o AOT nativo em um arquivo de projeto:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
Essa configuração permite a compilação AOT nativa durante a publicação e permite a análise dinâmica do uso de código durante a compilação e edição. Um projeto que usa a publicação AOT nativa usa a compilação JIT quando executado localmente. Um aplicativo AOT tem as seguintes diferenças de um aplicativo compilado por JIT:
- Os recursos que não são compatíveis com o AOT nativo são desativados e lançam exceções em tempo de execução.
- Um analisador de código-fonte está habilitado para destacar o código que não é compatível com o AOT nativo. No momento da publicação, todo o aplicativo, incluindo os pacotes NuGet, é analisado quanto à compatibilidade novamente.
A análise AOT nativa inclui todo o código do aplicativo e as bibliotecas das quais o aplicativo depende. Revise os avisos de AOT nativos e tome medidas corretivas. É uma boa ideia publicar aplicativos com frequência para descobrir problemas no início do ciclo de vida do desenvolvimento.
No .NET 8, a AOT nativa é suportada pelos seguintes tipos de aplicativo ASP.NET Core:
- APIs mínimas - Para obter mais informações, consulte a seção modelo de API da Web (AOT nativa) mais adiante neste artigo.
- gRPC - Para mais informações, consulte gRPC e AOT Nativo.
- Serviços de trabalhador - Para obter mais informações, consulte AOT em Modelos de serviço de trabalhador.
O modelo de API da Web (AOT nativa)
O modelo de
- Usa apenas APIs mínimas, pois o MVC ainda não é compatível com AOT nativo.
- Usa a API CreateSlimBuilder() para garantir que apenas os recursos essenciais sejam habilitados por padrão, minimizando o tamanho implantado do aplicativo.
- Está configurado para escutar somente em HTTP, pois o tráfego HTTPS é normalmente tratado por um serviço de entrada em implantações nativas da nuvem.
- Não inclui um perfil de inicialização para execução no IIS ou IIS Express.
- Cria um ficheiro
.http
configurado com solicitações HTTP de exemplo que podem ser enviadas para os endpoints da aplicação. - Inclui uma amostra
Todo
API em vez da amostra de previsão do tempo. - Adiciona
PublishAot
ao arquivo de projeto, conforme mostrado anteriormente neste artigo. - Habilita os geradores de código-fonte do serializador JSON . O gerador de código-fonte é usado para gerar código de serialização em tempo de compilação, o que é necessário para a compilação AOT nativa.
Alterações para dar suporte à geração de código-fonte
O exemplo a seguir mostra o código adicionado ao arquivo Program.cs
para dar suporte à geração de origem de serialização 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
+{
+
+}
Sem esse código adicionado, System.Text.Json
usa reflexão para serializar e desserializar JSON. A reflexão não é suportada em Native AOT.
Para mais informações, consulte:
Alterações ao launchSettings.json
O arquivo
{
"$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"
- }
- }
}
}
O método CreateSlimBuilder
O modelo usa o método CreateSlimBuilder() em vez do método 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
{
}
O método CreateSlimBuilder
inicializa o WebApplicationBuilder com o mínimo de recursos ASP.NET Core necessários para executar um aplicativo.
Como observado anteriormente, o método CreateSlimBuilder
não inclui suporte para HTTPS ou HTTP/3. Esses protocolos normalmente não são necessários para aplicativos executados atrás de um proxy de terminação TLS. Por exemplo, consulte terminação TLS e TLS de ponta a ponta com o Application Gateway. O HTTPS pode ser ativado ao invocar construtor.WebHost.UseKestrelHttpsConfiguration. O HTTP/3 pode ser ativado ao invocar construtor.WebHost.UseQuic.
CreateSlimBuilder
vs CreateBuilder
O método CreateSlimBuilder
não suporta os seguintes recursos que são suportados pelo método CreateBuilder
:
- Hospedagem de assemblies de inicialização
- UseStartup
- Os seguintes provedores de log:
- Recursos de hospedagem na Web:
- Kestrel configuração
- restrições Regex e alfa usadas no roteamento
O método CreateSlimBuilder
inclui os seguintes recursos necessários para uma experiência de desenvolvimento eficiente:
- Configuração do arquivo JSON para
appsettings.json
eappsettings.{EnvironmentName}.json
. - Configuração de segredos do usuário.
- Registro de console.
- Configuração de registo.
Para um construtor que omite as funcionalidades anteriores, consulte o método CreateEmptyBuilder
.
A inclusão de características mínimas tem benefícios para a otimização, assim como para o AOT. Para obter mais informações, consulte Reduzir implantações independentes e executáveis.
Para obter informações mais detalhadas, consulte Comparando WebApplication.CreateBuilder
com CreateSlimBuilder
Geradores de origem
Como o código não utilizado é cortado durante a publicação para AOT nativo, o aplicativo não pode usar reflexão ilimitada em tempo de execução. Geradores de código-fonte são usados para produzir código que evita a necessidade de reflexão. Em alguns casos, os geradores de código-fonte produzem código otimizado para AOT, mesmo quando um gerador não é necessário.
Para exibir o código-fonte gerado, adicione a propriedade EmitCompilerGeneratedFiles
ao arquivo .csproj
de um aplicativo, conforme mostrado no exemplo a seguir:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Other properties omitted for brevity -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
</Project>
Execute o comando dotnet build
para ver o código gerado. A saída inclui um diretório obj/Debug/net8.0/generated/
que contém todos os arquivos gerados para o projeto.
O comando dotnet publish
também compila os arquivos de origem e gera arquivos que são compilados. Além disso, dotnet publish
passa os assemblies gerados para um compilador IL nativo. O compilador IL produz o executável nativo. O executável nativo contém o código da máquina nativa.
Bibliotecas e AOT nativo
Muitas das bibliotecas populares usadas em projetos ASP.NET Core atualmente têm alguns problemas de compatibilidade quando usadas em um projeto direcionado à AOT nativa, como:
- Uso da reflexão para inspecionar e descobrir tipos.
- Carregamento condicional de bibliotecas em tempo de execução.
- Geração de código em tempo real para implementar funcionalidades.
As bibliotecas que usam esses recursos dinâmicos precisam ser atualizadas para trabalhar com AOT nativo. Eles podem ser atualizados usando ferramentas como geradores de fontes Roslyn.
Os autores de bibliotecas que desejam apoiar o Native AOT são encorajados a:
- Leia sobre os requisitos de compatibilidade de AOT nativo .
- Preparar a biblioteca para cortar.
APIs mínimas e cargas úteis JSON
A API Mínima é otimizada para receber e retornar dados JSON usando System.Text.Json.
System.Text.Json
:
- Impõe requisitos de compatibilidade para JSON e AOT nativo.
- Requer o uso do gerador de fonte
System.Text.Json
.
Todos os tipos transmitidos como parte do corpo HTTP ou retornados de delegados de solicitação em aplicativos de APIs mínimas devem ser configurados em um JsonSerializerContext registrado por meio da injeção de dependência do 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
{
}
No código destacado anterior:
- O contexto do serializador JSON é registado com o container DI. Para mais informações, consulte:
- O
JsonSerializerContext
personalizado é anotado com o atributo[JsonSerializable]
para habilitar o código serializador JSON gerado pela fonte para o tipoToDo
.
Um parâmetro no delegado que não está vinculado ao corpo e não precisa ser serializável. Por exemplo, um parâmetro de cadeia de caracteres de consulta que é um tipo de objeto avançado e implementa 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.
Problemas conhecidos
Consulte este problema do GitHub para relatar ou revisar problemas com o suporte nativo de AOT no ASP.NET Core.
Ver também
- Tutorial: Publicar um aplicativo ASP.NET Core usando o AOT nativo
- Implantação de AOT nativo
- Otimizar implantações de AOT
- Gerador de código-fonte de ligação de configuração
- pt-PT: Usando o gerador de código-fonte do vinculador de configuração
- O modelo de compilação AOT de API mínima
-
Comparando
WebApplication.CreateBuilder
comCreateSlimBuilder
- Explorando o novo gerador de código-fonte de API mínimo
- Substituindo chamadas de método por Intercetores
-
Por trás do novo gerador de registo de telemetria
[LogProperties]
ASP.NET Core 8.0 introduz suporte para de antecipação (AOT) nativo do .NET.
Por que usar AOT nativo com ASP.NET Core
Publicar e implantar um aplicativo AOT nativo oferece os seguintes benefícios:
-
Minimized disk footprint: Ao publicar usando AOT nativo, um único executável é produzido contendo apenas o código de dependências externas que é necessário para dar suporte ao programa. O tamanho reduzido do executável pode levar a:
- Imagens de contentor menores, por exemplo, em cenários de implementação em contentores.
- Tempo de implantação reduzido a partir de imagens menores.
-
Tempo de inicialização reduzido: Os aplicativos AOT nativos podem mostrar tempos de inicialização reduzidos, o que significa
- O aplicativo está pronto para atender solicitações mais rapidamente.
- Implantação aprimorada em que os orquestradores de contêineres precisam gerenciar a transição de uma versão do aplicativo para outra.
- Demanda de memória reduzida: Os aplicativos AOT nativos podem ter demandas de memória reduzidas, dependendo do trabalho feito pelo aplicativo. O consumo reduzido de memória pode levar a uma maior densidade de implantação e melhor escalabilidade.
O aplicativo de modelo foi executado em nosso laboratório de benchmarking para comparar o desempenho de um aplicativo publicado pela AOT, um aplicativo de tempo de execução cortado e um aplicativo de tempo de execução não cortado. O gráfico a seguir mostra os resultados do benchmarking:
O gráfico anterior mostra que a AOT nativa tem menor tamanho de aplicativo, uso de memória e tempo de inicialização.
ASP.NET Core e Compatibilidade com AOT Nativo
Nem todos os recursos do ASP.NET Core são atualmente compatíveis com a AOT nativa. A tabela a seguir resume a compatibilidade das funcionalidades do ASP.NET Core com a AOT nativa.
Funcionalidade | Totalmente suportado | Parcialmente suportado | Não suportado |
---|---|---|---|
gRPC | ✔️ Totalmente suportado | ||
APIs mínimas | ✔️ Parcialmente suportado | ||
MVC | Não suportado | ||
Blazor Server | Não suportado | ||
SignalR | Não suportado | ||
Autenticação JWT | ✔️ Totalmente suportado | ||
Outra autenticação | Não suportado | ||
CORS | ✔️ Totalmente suportado | ||
Verificações de saúde | ✔️ Totalmente suportado | ||
HttpLogging | ✔️ Totalmente suportado | ||
Localização | ✔️ Totalmente suportado | ||
OutputCaching | ✔️ Totalmente suportado | ||
Limitação de Taxa | ✔️ Totalmente suportado | ||
Requisição de Descompressão | ✔️ Totalmente suportado | ||
ResponseCaching | ✔️ Totalmente suportado | ||
Compressão de Resposta | ✔️ Totalmente suportado | ||
Reescrever | ✔️ Totalmente suportado | ||
Sessão | Não suportado | ||
Termas | Não suportado | ||
Arquivos Estáticos | ✔️ Totalmente suportado | ||
WebSockets | Totalmente suportado ✔️ |
Para obter mais informações sobre limitações, consulte:
- Limitações na implantação de AOT nativo
- Introdução aos avisos AOT
- Incompatibilidades de corte conhecidas
- Introdução aos avisos de corte
- Problema do GitHub dotnet/core #8288
É importante testar um aplicativo completamente ao mudar para um modelo de implantação AOT nativo. A aplicação implantada pela AOT deve ser testada para assegurar que a funcionalidade se mantém inalterada em relação à aplicação sem reduções e compilada com JIT. Ao criar o aplicativo, revise e corrija os avisos da AOT. Uma aplicação que emite avisos de AOT durante a publicação pode não funcionar corretamente. Se nenhum aviso de AOT for emitido no momento da publicação, a aplicação AOT publicada deverá operar da mesma forma que a aplicação não reduzida e compilada por JIT.
Publicação nativa de AOT
O AOT nativo é habilitado com a propriedade PublishAot
MSBuild. O exemplo a seguir mostra como habilitar o AOT nativo em um arquivo de projeto:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
Essa configuração permite a compilação AOT nativa durante a publicação e permite a análise dinâmica do uso de código durante a compilação e edição. Um projeto que usa a publicação AOT nativa usa a compilação JIT quando executado localmente. Um aplicativo AOT tem as seguintes diferenças de um aplicativo compilado por JIT:
- Os recursos que não são compatíveis com o AOT nativo são desativados e lançam exceções em tempo de execução.
- Um analisador de código-fonte está habilitado para destacar o código que não é compatível com o AOT nativo. No momento da publicação, todo o aplicativo, incluindo os pacotes NuGet, é analisado quanto à compatibilidade novamente.
A análise AOT nativa inclui todo o código do aplicativo e as bibliotecas das quais o aplicativo depende. Revise os avisos de AOT nativos e tome medidas corretivas. É uma boa ideia publicar aplicativos com frequência para descobrir problemas no início do ciclo de vida do desenvolvimento.
No .NET 8, a AOT nativa é suportada pelos seguintes tipos de aplicativo ASP.NET Core:
- APIs mínimas - Para obter mais informações, consulte a seção modelo de API da Web (AOT nativa) mais adiante neste artigo.
- gRPC - Para obter mais informações, consulte gRPC e AOT Nativo.
- Serviços de trabalhador - Para obter mais informações, consulte AOT em Modelos de serviço de trabalhador.
O modelo de API da Web (AOT nativa)
O modelo de
- Usa apenas APIs mínimas, pois o MVC ainda não é compatível com AOT nativo.
- Usa a API CreateSlimBuilder() para garantir que apenas os recursos essenciais sejam habilitados por padrão, minimizando o tamanho implantado do aplicativo.
- Está configurado para escutar somente em HTTP, pois o tráfego HTTPS é normalmente tratado por um serviço de entrada em implantações nativas da nuvem.
- Não inclui um perfil de inicialização para execução no IIS ou IIS Express.
- Cria um ficheiro
.http
configurado com exemplos de pedidos HTTP que podem ser enviados para os endpoints da aplicação. - Inclui uma amostra
Todo
API em vez da amostra de previsão do tempo. - Adiciona
PublishAot
ao arquivo de projeto, conforme mostrado anteriormente neste artigo. - Ativa os geradores de código fonte do serializador JSON . O gerador de código-fonte é usado para gerar código de serialização em tempo de compilação, o que é necessário para a compilação AOT nativa.
Alterações para dar suporte à geração de código-fonte
O exemplo a seguir mostra o código adicionado ao arquivo Program.cs
para dar suporte à geração de origem de serialização 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
+{
+
+}
Sem esse código adicionado, System.Text.Json
usa reflexão para serializar e desserializar JSON. A reflexão não é suportada no Native AOT.
Para mais informações, consulte:
Alterações ao launchSettings.json
O arquivo
{
"$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"
- }
- }
}
}
O método CreateSlimBuilder
O modelo usa o método CreateSlimBuilder() em vez do método 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
{
}
O método CreateSlimBuilder
inicializa o WebApplicationBuilder com o mínimo de recursos ASP.NET Core necessários para executar um aplicativo.
Como observado anteriormente, o método CreateSlimBuilder
não inclui suporte para HTTPS ou HTTP/3. Esses protocolos normalmente não são necessários para aplicativos executados atrás de um proxy de terminação TLS. Por exemplo, consulte a terminação TLS e o TLS de ponta a ponta com o Application Gateway. O HTTPS pode ser ativado chamando builder.WebHost.UseKestrelHttpsConfiguration, e o HTTP/3 pode ser ativado chamando builder.WebHost.UseQuic.
CreateSlimBuilder
vs CreateBuilder
O método CreateSlimBuilder
não suporta os seguintes recursos que são suportados pelo método CreateBuilder
:
- Hospedagem de assemblies de inicialização
- UseStartup
- Os seguintes provedores de registo:
- Recursos de hospedagem na Web:
- Kestrel configuração
- restrições Regex e alfa usadas no roteamento
O método CreateSlimBuilder
inclui os seguintes recursos necessários para uma experiência de desenvolvimento eficiente:
- Configuração do arquivo JSON para
appsettings.json
eappsettings.{EnvironmentName}.json
. - Configuração de segredos do usuário.
- Registro de consola.
- Configuração de registo.
Para um construtor que omite os recursos anteriores, consulte O método CreateEmptyBuilder
.
A inclusão de recursos mínimos tem benefícios para otimização, assim como para AOT. Para obter mais informações, consulte Otimizar implantações independentes e executáveis.
Para obter informações mais detalhadas, consulte Comparando WebApplication.CreateBuilder
com CreateSlimBuilder
Geradores de origem
Como o código não utilizado é cortado durante a publicação para AOT nativo, o aplicativo não pode usar reflexão ilimitada em tempo de execução. Geradores de código-fonte são usados para produzir código que evita a necessidade de reflexão. Em alguns casos, os geradores de código-fonte produzem código otimizado para AOT, mesmo quando um gerador não é necessário.
Para exibir o código-fonte gerado, adicione a propriedade EmitCompilerGeneratedFiles
ao arquivo .csproj
de um aplicativo, conforme mostrado no exemplo a seguir:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Other properties omitted for brevity -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
</Project>
Execute o comando dotnet build
para ver o código gerado. A saída inclui um diretório obj/Debug/net8.0/generated/
que contém todos os arquivos gerados para o projeto.
O comando dotnet publish
também compila os arquivos de origem e gera arquivos que são compilados. Além disso, dotnet publish
passa os assemblies gerados para um compilador IL nativo. O compilador IL produz o executável nativo. O executável nativo contém o código da máquina nativa.
Bibliotecas e AOT nativo
Muitas das bibliotecas populares usadas em projetos ASP.NET Core atualmente têm alguns problemas de compatibilidade quando usadas em um projeto direcionado à AOT nativa, como:
- Uso da reflexão para inspecionar e descobrir tipos.
- Carregamento condicional de bibliotecas em tempo de execução.
- Geração de código em tempo real para implementar funcionalidades.
As bibliotecas que usam esses recursos dinâmicos precisam ser atualizadas para trabalhar com AOT nativo. Eles podem ser atualizados usando ferramentas como geradores de fontes Roslyn.
Os autores de bibliotecas que desejam dar suporte ao AOT nativo são incentivados a:
APIs básicas e cargas úteis de JSON
A estrutura de API mínima está otimizada para receber e retornar dados JSON usando System.Text.Json.
System.Text.Json
:
- Impõe requisitos de compatibilidade para JSON e AOT nativo.
- Requer o uso do gerador de fonte
System.Text.Json
.
Todos os tipos transmitidos como parte do corpo HTTP ou retornados de delegados de solicitação em aplicações de APIs Mínimas devem ser configurados num JsonSerializerContext que esteja registado por meio da injeção de dependência do 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
{
}
No código anteriormente destacado:
- O contexto do serializador JSON é registrado com o contêiner DI. Para mais informações, consulte:
- O
JsonSerializerContext
personalizado é anotado com o atributo[JsonSerializable]
para habilitar o código serializador JSON gerado pela fonte para o tipoToDo
.
Um parâmetro no delegado que não está vinculado ao corpo e não precisa ser serializável. Por exemplo, um parâmetro de cadeia de caracteres de consulta que é um tipo de objeto avançado e implementa 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.
Problemas conhecidos
Consulte o problema do GitHub para relatar ou rever questões relacionadas com o suporte nativo de AOT no ASP.NET Core.
Ver também
- Tutorial: Publicar um aplicativo ASP.NET Core usando o AOT nativo
- Implementação de AOT Nativo
- Otimizar implantações de AOT
- Gerador de fonte de ligação de configuração
- Usando o gerador de código-fonte do associador de configuração
- O modelo de compilação AOT de API mínima
-
Comparando
WebApplication.CreateBuilder
comCreateSlimBuilder
- Explorando o novo gerador de código-fonte de API mínimo
- Substituindo chamadas de método por Interceptors
-
Atrás de
[LogProperties]
e o novo gerador de fontes para registo de telemetria