Partilhar via


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:

Gráfico mostrando a comparação do tamanho do aplicativo, uso de memória e métricas de tempo de inicialização 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 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:

É 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:

O modelo de API da Web (AOT nativa)

O modelo de ASP.NET Core Web API (Native AOT) (nome abreviado ) cria um projeto com AOT habilitado. O modelo difere da API Web modelo de projeto das seguintes maneiras:

  • 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 criado pelo modelo de da API Web (AOT nativa) tem a seção e o perfil removidos:

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

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 e appsettings.{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:

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:

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

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:

Gráfico mostrando a comparação do tamanho do aplicativo, uso de memória e métricas de tempo de inicialização 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 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:

É 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:

O modelo de API da Web (AOT nativa)

O modelo de ASP.NET Core Web API (Native AOT) (nome abreviado ) cria um projeto com AOT ativado. O modelo difere da API Web modelo de projeto das seguintes maneiras:

  • 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 criado pelo modelo de da API Web (AOT nativa) tem a seção e o perfil removidos:

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

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 e appsettings.{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:

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