Compatibilidad de ASP.NET Core con AOT nativo
De Mitch Denny
ASP.NET Core 8.0 ofrece compatibilidad con .NET ahead-of-time (AOT) nativo.
Para obtener una guía sobre AOT nativo de Blazor WebAssembly, que se agregue o reemplace la guía en este artículo, consulta Herramientas de compilación y compilación Ahead Of Time (AOT) de Blazor WebAssembly en ASP.NET Core.
Razones para usar AOT nativo con ASP.NET Core
La publicación e implementación de una aplicación de AOT nativo proporciona las siguientes ventajas:
- Superficie de disco minimizada: al publicar con AOT nativo, se genera un único archivo ejecutable que contiene solo el código de las dependencias externas que se necesitan para respaldar el programa. El tamaño reducido de archivo ejecutable puede dar lugar a:
- Imágenes de contenedor más pequeñas; por ejemplo, en escenarios de implementación en contenedores.
- Tiempo de implementación reducido de las imágenes más pequeñas.
- Menor tiempo de inicio: las aplicaciones de AOT nativo logran unos tiempos de inicio reducidos, lo que significa que:
- La aplicación está lista para atender las solicitudes más rápidamente.
- La implementación mejora cuando los orquestadores de contenedores necesitan administrar la transición de una versión de la aplicación a otra.
- Menor demanda de memoria: las aplicaciones de AOT nativo pueden tener una menor demanda de memoria en función del trabajo que la aplicación realice. El menor consumo de memoria puede dar lugar a una mayor densidad de implementación y a una mejor escalabilidad.
Hemos ejecutado la aplicación de plantilla en nuestro laboratorio de pruebas comparativas para cotejar el rendimiento de una aplicación publicada con AOT, de una aplicación en tiempo de ejecución recortada y de una aplicación en tiempo de ejecución sin recortar. En el siguiente gráfico se muestran los resultados de la prueba comparativa:
En el gráfico anterior se muestra que AOT nativo tiene un tamaño de aplicación, un uso de memoria y un tiempo de inicio más reducidos.
ASP.NET Core y compatibilidad con AOT nativo
No todas las características de ASP.NET Core son actualmente compatibles con AOT nativo. En la tabla siguiente se resume la compatibilidad de las características de ASP.NET Core con AOT nativo:
Característica | Compatibilidad total | Se admite parcialmente | No compatible |
---|---|---|---|
gRPC | Compatibilidad total | ||
API mínimas | Compatibilidad parcial | ||
MVC | No compatible | ||
Blazor Server | No compatible | ||
SignalR | Compatibilidad parcial | ||
Autenticación JWT | Compatibilidad total | ||
Otra autenticación | No compatible | ||
CORS | Compatibilidad total | ||
HealthChecks | Compatibilidad total | ||
HttpLogging | Compatibilidad total | ||
Localización | Compatibilidad total | ||
OutputCaching | Compatibilidad total | ||
RateLimiting | Compatibilidad total | ||
RequestDecompression | Compatibilidad total | ||
ResponseCaching | Compatibilidad total | ||
ResponseCompression | Compatibilidad total | ||
Rewrite | Compatibilidad total | ||
Sesión | No compatible | ||
Spa | No compatible | ||
StaticFiles | Compatibilidad total | ||
WebSockets | Compatibilidad total |
Para obtener más información sobre las limitaciones, consulte:
- Limitaciones de la implementación con AOT nativo
- Introducción a las advertencias AOT
- Incompatibilidades conocidas de recorte
- Introducción a las advertencias de recorte
- Problema de GitHub dotnet/core #8288
Al cambiar a un modelo de implementación de AOT nativo, es importante probar una aplicación exhaustivamente. La aplicación de AOT implementada debe probarse para comprobar que la funcionalidad no ha cambiado respecto a la aplicación sin recortar y con compilación JIT. Al compilar la aplicación, examine y corrija las advertencias de AOT. Es posible que una aplicación que emite advertencias de AOT durante la publicación no funcione correctamente. Si no se emite ninguna advertencia de AOT en el momento de la publicación, la aplicación AOT publicada debe funcionar igual que la aplicación compilada sin intentar y JIT.
Publicación de AOT nativo
AOT nativo se habilita con la propiedad de MSBuild PublishAot
: En el siguiente ejemplo se muestra cómo habilitar AOT nativo en un archivo de proyecto:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
Esta configuración habilita la compilación de AOT nativo durante la publicación y el análisis dinámico del uso de código en el transcurso de la compilación y la edición. Un proyecto que usa la publicación de AOT nativo utiliza la compilación JIT cuando se ejecuta de forma local. Una aplicación AOT presenta las siguientes diferencias con respecto a una aplicación compilada por JIT:
- Las características que no son compatibles con AOT nativo se deshabilitan y producen excepciones en tiempo de ejecución.
- Un analizador de origen está habilitado para resaltar el código que no es compatible con AOT nativo. En el momento de publicación, se analizará la aplicación completa, incluidos los paquetes NuGet, con fines de compatibilidad.
El análisis de AOT nativo abarca todo el código de la aplicación y las bibliotecas de las que esta depende. Revise las advertencias de AOT nativo y tome medidas correctivas. Se recomienda publicar las aplicaciones con frecuencia para detectar problemas lo antes posible en el ciclo de vida de desarrollo.
En .NET 8, AOT nativo es compatible con los siguientes tipos de aplicación ASP.NET Core:
- API mínimas: para más información, consulte la sección Plantilla de API web (AOT nativa) más adelante en este artículo.
- gRPC: para más información, consulte gRPC y AOT nativo.
- Worker Services: para obtener más información, vea AOT en plantillas de Worker Service.
Plantilla de API web (AOT nativa)
La plantilla ASP.NET Core Web API (AOT nativa) (nombre corto webapiaot
) crea un proyecto con AOT habilitado. La plantilla difiere de la plantilla de proyecto Web API de las siguientes maneras:
- Usa solo API mínimas, ya que MVC aún no es compatible con AOT nativo.
- Usa la API CreateSlimBuilder() para garantizar que solo las características esenciales están habilitadas de forma predeterminada, lo que reduce al mínimo el tamaño implementado de la aplicación.
- Está configurada para escuchar solo HTTP, ya que en las implementaciones nativas de nube el tráfico HTTPS suele estar controlado por un servicio de entrada.
- No incluye un perfil de inicio para ejecutarse en IIS o IIS Express.
- Crea un archivo
.http
configurado con solicitudes HTTP de ejemplo que se pueden enviar a los puntos de conexión de la aplicación. - Incluye una API
Todo
de ejemplo en lugar del ejemplo de previsión meteorológica. - Agrega
PublishAot
al archivo de proyecto, tal y como hemos visto anteriormente en este artículo. - Habilita los generadores de origen del serializador JSON. Los generadores de código fuente se usan para generar código de serialización en tiempo de compilación, lo cual es necesario para la compilación AOT nativa.
Cambios para admitir la generación de orígenes
En el siguiente ejemplo se muestra el código agregado al archivo Program.cs
para admitir la generación de orígenes de serialización 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
+{
+
+}
Sin este código agregado, System.Text.Json
usa la reflexión para serializar y deserializar JSON. La reflexión no se admite en AOT nativo.
Para más información, consulte:
Cambios a launchSettings.json
El archivo launchSettings.json
creado por la plantilla de API web (AOT nativo) tiene la sección iisSettings
y el perfil IIS Express
quitados:
{
"$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"
- }
- }
}
}
El método CreateSlimBuilder
La plantilla usa el método CreateSlimBuilder() en vez del 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
{
}
El método CreateSlimBuilder
inicializa WebApplicationBuilder con las características de ASP.NET Core mínimas necesarias para ejecutar una aplicación.
Como hemos señalado anteriormente, el método CreateSlimBuilder
no incluye compatibilidad con HTTPS ni HTTP/3. Normalmente, estos protocolos no son necesarios para las aplicaciones que se ejecutan detrás de un proxy de terminación TLS. Por ejemplo, vea Terminación TLS y TLS de un extremo a otro con Application Gateway. HTTPS se puede habilitar llamando a builder.WebHost.UseKestrelHttpsConfiguration HTTP/3 se puede habilitar llamando a builder.WebHost.UseQuic.
CreateSlimBuilder
frente a CreateBuilder
El método CreateSlimBuilder
no admite las siguientes características compatibles con el método CreateBuilder
:
- Ensamblados de inicio de hospedaje
- UseStartup
- Los siguientes proveedores de registro:
- Características de hospedaje web:
- Configuración de Kestrel
- Restricciones regex y alfa usadas en el enrutamiento
El método CreateSlimBuilder
incluye las siguientes características necesarias para una experiencia de desarrollo eficaz:
- Configuración del archivo JSON para
appsettings.json
yappsettings.{EnvironmentName}.json
. - Configuración de secretos de usuario
- Registro de consolas
- Configuración del registro
Para obtener un generador que omita las características anteriores, vea El método CreateEmptyBuilder
.
Incluir las características mínimas es beneficioso para el recorte, así como para AOT. Para obtener más información, vea Recorte de implementaciones autocontenidas y ejecutables.
Para obtener información más detallada, consulte Comparación WebApplication.CreateBuilder
con CreateSlimBuilder
Generadores de origen
Dado que el código sin usar se recorta durante la publicación para AOT nativo, la aplicación no puede usar la reflexión sin enlazar en tiempo de ejecución. Los generadores de código fuente sirven para generar código y evitan tener que recurrir a la reflexión. En algunos casos, los generadores de código fuente generan código optimizado para AOT, incluso cuando no es necesario un generador.
Para ver el código fuente generado, agregue la propiedad EmitCompilerGeneratedFiles
al archivo .csproj
de una aplicación, como se muestra en el siguiente ejemplo:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Other properties omitted for brevity -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
</Project>
Ejecute el comando dotnet build
para ver el código generado. La salida incluye un directorio obj/Debug/net8.0/generated/
que contiene todos los archivos generados del proyecto.
El comando dotnet publish
también compila los archivos de origen y genera archivos que se compilan. Asimismo, dotnet publish
pasa los ensamblados generados a un compilador de IL nativo. El compilador de IL genera el ejecutable nativo. El archivo ejecutable nativo contiene el código de máquina nativo.
Bibliotecas y AOT nativo
Muchas de las bibliotecas populares que se usan en los proyectos de ASP.NET Core actualmente tienen algunos problemas de compatibilidad cuando se utilizan en un proyecto que tiene como destino AOT nativo, por ejemplo:
- Uso de la reflexión para inspeccionar y detectar tipos.
- Carga condicional de bibliotecas en tiempo de ejecución.
- Generar código sobre la marcha para implementar la funcionalidad.
Las bibliotecas que usan estas características dinámicas se deben actualizar para poder trabajar con AOT nativo. Se pueden actualizar usando herramientas como generadores de origen de Roslyn.
A los creadores de bibliotecas que quieran admitir AOT nativo se les recomienda lo siguiente:
- Obtenga información sobre los requisitos de compatibilidad de AOT nativo.
- Prepare la biblioteca para el recorte.
API mínimas y cargas de JSON
El marco de API mínimo está optimizado para recibir y devolver cargas JSON mediante System.Text.Json. System.Text.Json
:
- Impone requisitos de compatibilidad para JSON y AOT nativo.
- Requiere el uso del
System.Text.Json
generadorde origen.
Todos los tipos que se transmiten como parte del cuerpo HTTP o que se devuelven de delegados de solicitud en aplicaciones de API mínimas deben configurarse en un JsonSerializerContext que se registra a través de la inserción de dependencias de 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
{
}
En el código resaltado anterior:
- El contexto del serializador JSON se registra con el contenedor de inserción de dependencias. Para obtener más información, consulta:
- El
JsonSerializerContext
personalizado se anota con el atributo[JsonSerializable]
para habilitar el código del serializador JSON generado por el origen para el tipoToDo
.
Parámetro del delegado que no está enlazado al cuerpo y no es necesario serializable. Por ejemplo, un parámetro de cadena de consulta que es un tipo de objeto enriquecido 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 conocidos
Consulte este problema de GitHub para notificar o revisar los problemas de compatibilidad con AOT nativo en ASP.NET Core.
Consulte también
- Tutorial: Publicación de una aplicación de ASP.NET Core mediante AOT nativo
- Implementación de AOT nativo
- Optimización de implementaciones de AOT
- Generador de origen de enlace de configuración
- Uso del generador de origen del enlazador de configuración
- Plantilla de compilación AOT de API mínima
- Comparación de
WebApplication.CreateBuilder
conCreateSlimBuilder
- Exploración del nuevo generador de origen de API mínimo
- Sustitución de llamadas de método por interceptores
- Detrás de
[LogProperties]
y el nuevo generador de origen de registro de telemetría
ASP.NET Core 8.0 ofrece compatibilidad con .NET ahead-of-time (AOT) nativo.
Razones para usar AOT nativo con ASP.NET Core
La publicación e implementación de una aplicación de AOT nativo proporciona las siguientes ventajas:
- Superficie de disco minimizada: al publicar con AOT nativo, se genera un único archivo ejecutable que contiene solo el código de las dependencias externas que se necesitan para respaldar el programa. El tamaño reducido de archivo ejecutable puede dar lugar a:
- Imágenes de contenedor más pequeñas; por ejemplo, en escenarios de implementación en contenedores.
- Tiempo de implementación reducido de las imágenes más pequeñas.
- Menor tiempo de inicio: las aplicaciones de AOT nativo logran unos tiempos de inicio reducidos, lo que significa que:
- La aplicación está lista para atender las solicitudes más rápidamente.
- La implementación mejora cuando los orquestadores de contenedores necesitan administrar la transición de una versión de la aplicación a otra.
- Menor demanda de memoria: las aplicaciones de AOT nativo pueden tener una menor demanda de memoria en función del trabajo que la aplicación realice. El menor consumo de memoria puede dar lugar a una mayor densidad de implementación y a una mejor escalabilidad.
Hemos ejecutado la aplicación de plantilla en nuestro laboratorio de pruebas comparativas para cotejar el rendimiento de una aplicación publicada con AOT, de una aplicación en tiempo de ejecución recortada y de una aplicación en tiempo de ejecución sin recortar. En el siguiente gráfico se muestran los resultados de la prueba comparativa:
En el gráfico anterior se muestra que AOT nativo tiene un tamaño de aplicación, un uso de memoria y un tiempo de inicio más reducidos.
ASP.NET Core y compatibilidad con AOT nativo
No todas las características de ASP.NET Core son actualmente compatibles con AOT nativo. En la tabla siguiente se resume la compatibilidad de las características de ASP.NET Core con AOT nativo:
Característica | Compatibilidad total | Se admite parcialmente | No compatible |
---|---|---|---|
gRPC | Compatibilidad total | ||
API mínimas | Compatibilidad parcial | ||
MVC | No compatible | ||
Blazor Server | No compatible | ||
SignalR | No compatible | ||
Autenticación JWT | Compatibilidad total | ||
Otra autenticación | No compatible | ||
CORS | Compatibilidad total | ||
HealthChecks | Compatibilidad total | ||
HttpLogging | Compatibilidad total | ||
Localización | Compatibilidad total | ||
OutputCaching | Compatibilidad total | ||
RateLimiting | Compatibilidad total | ||
RequestDecompression | Compatibilidad total | ||
ResponseCaching | Compatibilidad total | ||
ResponseCompression | Compatibilidad total | ||
Rewrite | Compatibilidad total | ||
Sesión | No compatible | ||
Spa | No compatible | ||
StaticFiles | Compatibilidad total | ||
WebSockets | Compatibilidad total |
Para obtener más información sobre las limitaciones, consulte:
- Limitaciones de la implementación con AOT nativo
- Introducción a las advertencias AOT
- Incompatibilidades conocidas de recorte
- Introducción a las advertencias de recorte
- Problema de GitHub dotnet/core #8288
Al cambiar a un modelo de implementación de AOT nativo, es importante probar una aplicación exhaustivamente. La aplicación de AOT implementada debe probarse para comprobar que la funcionalidad no ha cambiado respecto a la aplicación sin recortar y con compilación JIT. Al compilar la aplicación, examine y corrija las advertencias de AOT. Es posible que una aplicación que emite advertencias de AOT durante la publicación no funcione correctamente. Si no se emite ninguna advertencia de AOT en el momento de la publicación, la aplicación AOT publicada debe funcionar igual que la aplicación compilada sin intentar y JIT.
Publicación de AOT nativo
AOT nativo se habilita con la propiedad de MSBuild PublishAot
: En el siguiente ejemplo se muestra cómo habilitar AOT nativo en un archivo de proyecto:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
Esta configuración habilita la compilación de AOT nativo durante la publicación y el análisis dinámico del uso de código en el transcurso de la compilación y la edición. Un proyecto que usa la publicación de AOT nativo utiliza la compilación JIT cuando se ejecuta de forma local. Una aplicación AOT presenta las siguientes diferencias con respecto a una aplicación compilada por JIT:
- Las características que no son compatibles con AOT nativo se deshabilitan y producen excepciones en tiempo de ejecución.
- Un analizador de origen está habilitado para resaltar el código que no es compatible con AOT nativo. En el momento de publicación, se analizará la aplicación completa, incluidos los paquetes NuGet, con fines de compatibilidad.
El análisis de AOT nativo abarca todo el código de la aplicación y las bibliotecas de las que esta depende. Revise las advertencias de AOT nativo y tome medidas correctivas. Se recomienda publicar las aplicaciones con frecuencia para detectar problemas lo antes posible en el ciclo de vida de desarrollo.
En .NET 8, AOT nativo es compatible con los siguientes tipos de aplicación ASP.NET Core:
- API mínimas: para más información, consulte la sección Plantilla de API web (AOT nativa) más adelante en este artículo.
- gRPC: para más información, consulte gRPC y AOT nativo.
- Worker Services: para obtener más información, vea AOT en plantillas de Worker Service.
Plantilla de API web (AOT nativa)
La plantilla ASP.NET Core Web API (AOT nativa) (nombre corto webapiaot
) crea un proyecto con AOT habilitado. La plantilla difiere de la plantilla de proyecto Web API de las siguientes maneras:
- Usa solo API mínimas, ya que MVC aún no es compatible con AOT nativo.
- Usa la API CreateSlimBuilder() para garantizar que solo las características esenciales están habilitadas de forma predeterminada, lo que reduce al mínimo el tamaño implementado de la aplicación.
- Está configurada para escuchar solo HTTP, ya que en las implementaciones nativas de nube el tráfico HTTPS suele estar controlado por un servicio de entrada.
- No incluye un perfil de inicio para ejecutarse en IIS o IIS Express.
- Crea un archivo
.http
configurado con solicitudes HTTP de ejemplo que se pueden enviar a los puntos de conexión de la aplicación. - Incluye una API
Todo
de ejemplo en lugar del ejemplo de previsión meteorológica. - Agrega
PublishAot
al archivo de proyecto, tal y como hemos visto anteriormente en este artículo. - Habilita los generadores de origen del serializador JSON. Los generadores de código fuente se usan para generar código de serialización en tiempo de compilación, lo cual es necesario para la compilación AOT nativa.
Cambios para admitir la generación de orígenes
En el siguiente ejemplo se muestra el código agregado al archivo Program.cs
para admitir la generación de orígenes de serialización 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
+{
+
+}
Sin este código agregado, System.Text.Json
usa la reflexión para serializar y deserializar JSON. La reflexión no se admite en AOT nativo.
Para más información, consulte:
Cambios a launchSettings.json
El archivo launchSettings.json
creado por la plantilla de API web (AOT nativo) tiene la sección iisSettings
y el perfil IIS Express
quitados:
{
"$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"
- }
- }
}
}
El método CreateSlimBuilder
La plantilla usa el método CreateSlimBuilder() en vez del 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
{
}
El método CreateSlimBuilder
inicializa WebApplicationBuilder con las características de ASP.NET Core mínimas necesarias para ejecutar una aplicación.
Como hemos señalado anteriormente, el método CreateSlimBuilder
no incluye compatibilidad con HTTPS ni HTTP/3. Normalmente, estos protocolos no son necesarios para las aplicaciones que se ejecutan detrás de un proxy de terminación TLS. Por ejemplo, vea Terminación TLS y TLS de un extremo a otro con Application Gateway. HTTPS se puede habilitar llamando a builder.WebHost.UseKestrelHttpsConfiguration HTTP/3 se puede habilitar llamando a builder.WebHost.UseQuic.
CreateSlimBuilder
frente a CreateBuilder
El método CreateSlimBuilder
no admite las siguientes características compatibles con el método CreateBuilder
:
- Ensamblados de inicio de hospedaje
- UseStartup
- Los siguientes proveedores de registro:
- Características de hospedaje web:
- Configuración de Kestrel
- Restricciones regex y alfa usadas en el enrutamiento
El método CreateSlimBuilder
incluye las siguientes características necesarias para una experiencia de desarrollo eficaz:
- Configuración del archivo JSON para
appsettings.json
yappsettings.{EnvironmentName}.json
. - Configuración de secretos de usuario
- Registro de consolas
- Configuración del registro
Para obtener un generador que omita las características anteriores, vea El método CreateEmptyBuilder
.
Incluir las características mínimas es beneficioso para el recorte, así como para AOT. Para obtener más información, vea Recorte de implementaciones autocontenidas y ejecutables.
Para obtener información más detallada, consulte Comparación WebApplication.CreateBuilder
con CreateSlimBuilder
Generadores de origen
Dado que el código sin usar se recorta durante la publicación para AOT nativo, la aplicación no puede usar la reflexión sin enlazar en tiempo de ejecución. Los generadores de código fuente sirven para generar código y evitan tener que recurrir a la reflexión. En algunos casos, los generadores de código fuente generan código optimizado para AOT, incluso cuando no es necesario un generador.
Para ver el código fuente generado, agregue la propiedad EmitCompilerGeneratedFiles
al archivo .csproj
de una aplicación, como se muestra en el siguiente ejemplo:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- Other properties omitted for brevity -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
</Project>
Ejecute el comando dotnet build
para ver el código generado. La salida incluye un directorio obj/Debug/net8.0/generated/
que contiene todos los archivos generados del proyecto.
El comando dotnet publish
también compila los archivos de origen y genera archivos que se compilan. Asimismo, dotnet publish
pasa los ensamblados generados a un compilador de IL nativo. El compilador de IL genera el ejecutable nativo. El archivo ejecutable nativo contiene el código de máquina nativo.
Bibliotecas y AOT nativo
Muchas de las bibliotecas populares que se usan en los proyectos de ASP.NET Core actualmente tienen algunos problemas de compatibilidad cuando se utilizan en un proyecto que tiene como destino AOT nativo, por ejemplo:
- Uso de la reflexión para inspeccionar y detectar tipos.
- Carga condicional de bibliotecas en tiempo de ejecución.
- Generar código sobre la marcha para implementar la funcionalidad.
Las bibliotecas que usan estas características dinámicas se deben actualizar para poder trabajar con AOT nativo. Se pueden actualizar usando herramientas como generadores de origen de Roslyn.
A los creadores de bibliotecas que quieran admitir AOT nativo se les recomienda lo siguiente:
- Obtenga información sobre los requisitos de compatibilidad de AOT nativo.
- Prepare la biblioteca para el recorte.
API mínimas y cargas de JSON
El marco de API mínimo está optimizado para recibir y devolver cargas JSON mediante System.Text.Json. System.Text.Json
:
- Impone requisitos de compatibilidad para JSON y AOT nativo.
- Requiere el uso del
System.Text.Json
generadorde origen.
Todos los tipos que se transmiten como parte del cuerpo HTTP o que se devuelven de delegados de solicitud en aplicaciones de API mínimas deben configurarse en un JsonSerializerContext que se registra a través de la inserción de dependencias de 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
{
}
En el código resaltado anterior:
- El contexto del serializador JSON se registra con el contenedor de inserción de dependencias. Para obtener más información, consulta:
- El
JsonSerializerContext
personalizado se anota con el atributo[JsonSerializable]
para habilitar el código del serializador JSON generado por el origen para el tipoToDo
.
Parámetro del delegado que no está enlazado al cuerpo y no es necesario serializable. Por ejemplo, un parámetro de cadena de consulta que es un tipo de objeto enriquecido 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 conocidos
Consulte este problema de GitHub para notificar o revisar los problemas de compatibilidad con AOT nativo en ASP.NET Core.
Consulte también
- Tutorial: Publicación de una aplicación de ASP.NET Core mediante AOT nativo
- Implementación de AOT nativo
- Optimización de implementaciones de AOT
- Generador de origen de enlace de configuración
- Uso del generador de origen del enlazador de configuración
- Plantilla de compilación AOT de API mínima
- Comparación de
WebApplication.CreateBuilder
conCreateSlimBuilder
- Exploración del nuevo generador de origen de API mínimo
- Sustitución de llamadas de método por interceptores
- Detrás de
[LogProperties]
y el nuevo generador de origen de registro de telemetría