Compartir a través de


Novedades de .NET.NET Aspire 9.0

📢 .NET Aspire 9.0 es la próxima versión principal de disponibilidad general (GA) de .NET Aspire; admite :

  • .NET 8.0 de soporte técnico a largo plazo (LTS) o
  • .NET Soporte de Términos Estándar (STS) 9.0.

Nota

¡Puede usar .NET Aspire 9.0 con .NET 8 o .NET 9!

Esta versión aborda algunas de las características más solicitadas y los puntos débiles de la comunidad. ¡Las mejores características son basadas en la comunidad! Para unirse a la comunidad, visite Discord para chatear con miembros del equipo y colaborar con nosotros en GitHub.

Para obtener más información sobre la versión oficial de .NET y la compatibilidad con versiones de .NET Aspire, consulte:

Actualización a .NET.NET Aspire 9

Para actualizar desde versiones anteriores de .NET Aspire a .NET Aspire 9, siga las instrucciones de la guía oficial de actualización de a .NET.NET Aspire 9. En la guía se proporcionan instrucciones detalladas sobre cómo actualizar las soluciones de .NET Aspire existentes a .NET Aspire 9. Independientemente de que lo esté haciendo manualmente o mediante el Asistente para actualización, la guía simplifica el proceso.

Mejoras en las herramientas

.NET Aspire 9 facilita la configuración del entorno para desarrollar aplicaciones .NET Aspire. Ya no necesita una carga de trabajo de .NET. En su lugar, instale el nuevo SDK de .NET.NET Aspire en el proyecto de host de aplicaciones de sus soluciones .NET.NET Aspire. Para obtener más información, consulte .NET.NET Aspire configuración y herramientas.

Las plantillas se han movido

.NET .NET Aspire 9 mueve el contenido que solía instalarse a través de la carga de trabajo en paquetes NuGet independientes. Esto incluye las plantillas para crear nuevos proyectos y soluciones de .NET.NET Aspire. Estas plantillas se instalan mediante el comando dotnet new install. Para instalarlos, ejecute el siguiente comando:

dotnet new install Aspire.ProjectTemplates::9.0.0

Propina

Si ya tiene instalada la carga de trabajo de .NET.NET Aspire, debe pasar la marca --force para sobrescribir las plantillas existentes. Puedes desinstalar la carga de trabajo de .NET.NET Aspire.

Para obtener más información, consulte plantillas de .NET.NET Aspire.

Mejoras de la experiencia del usuario del panel y nuevas características de interactividad

El panel de .NET.NET Aspire sigue mejorando con cada versión.

Administración del ciclo de vida de los recursos

La característica más solicitada para el panel es gestionar los ciclos de vida de sus recursos nombrados y orquestados. En concreto, la capacidad de detener, iniciar y reiniciar recursos. Esta característica funciona para proyectos, contenedores y ejecutables. Permite reiniciar recursos individuales sin tener que reiniciar todo el host de la aplicación. En el caso de los recursos del proyecto, cuando se adjunta el depurador, este se vuelve a adjuntar al reiniciar. Para obtener más información, consulte .NET.NET Aspire panel: Detener o Iniciar un recurso.

Compatibilidad con dispositivos móviles y soporte responsivo

El panel de .NET Aspire ahora es compatible con dispositivos móviles, adaptando de forma responsiva a una amplia gama de tamaños de pantalla y permitiendo gestionar sobre la marcha aplicaciones de .NET Aspire implementadas. Se realizaron otras mejoras de accesibilidad, incluida la visualización de la configuración y el desbordamiento de contenido en dispositivos móviles.

Propiedades confidenciales, volúmenes y verificaciones de salud en los detalles del recurso

La presentación de los detalles del recurso contiene varias mejoras:

  • Las propiedades se pueden marcar como confidenciales y enmascararlas automáticamente en la interfaz de usuario del panel. Esta característica de seguridad ayuda a evitar la divulgación accidental de claves o contraseñas al compartir el panel con otras personas. Por ejemplo, los argumentos de contenedor podrían pasar información confidencial, por lo que se enmascaran de forma predeterminada.

  • Los volúmenes de contenedor configurados se muestran en los detalles de los recursos.

  • .NET .NET Aspire 9 agrega soporte para las comprobaciones de salud. Ahora se puede ver información detallada sobre estas comprobaciones en el panel de detalles del recurso, que muestra por qué un recurso se puede marcar como incorrecto o degradado. Descubra más sobre las revisiones de salud aquí.

Registro colorido de consola

Los códigos de escape ANSI formatean texto en terminales mediante el control de colores (frontal y fondo) y estilos como negrita, subrayado y cursiva. Antes, la página de registros de la consola del panel solo podía representar un código de escape ANSI a la vez, fallando cuando se combinaban varios códigos. Por ejemplo, podría mostrar texto rojo, pero no texto que fuera rojo y en negrito.

Una contribución de la comunidad de @mangeg ha mejorado la compatibilidad con los códigos de escape ANSI y ha eliminado esta limitación.

Registros de consola coloridos

Otra mejora de los registros de consola es ocultar códigos de escape no admitidos. Los códigos que no están relacionados con la visualización de texto, como colocar el cursor o comunicarse con el sistema operativo no tienen sentido en esta interfaz de usuario y están ocultos.

Adiciones centradas en el usuario de telemetría

Telemetría sigue siendo un aspecto vital de .NET.NET Aspire. En .NET.NET Aspire 9, muchas características nuevas se introdujeron en el servicio telemetría.

Filtrado de telemetría mejorado

Los rastros se pueden filtrar con valores de atributo. Por ejemplo, si solo desea ver los seguimientos de un punto de conexión de la aplicación, el atributo http.route en las solicitudes HTTP se puede filtrar por un valor especificado.

El filtrado de telemetría también admite autocompletar para valores existentes. El cuadro de diálogo Agregar filtro proporciona un cuadro combinado para seleccionar entre los valores disponibles en el panel. Esta característica facilita mucho el filtrado a datos reales y ayuda a evitar errores tipográficos al escribir un valor usted mismo.

Para más información, consulte el tablero .NET.NET Aspire: Filtrar trazas.

Combinación de telemetría de varios recursos

Cuando un recurso tiene varias réplicas, ahora puede filtrar la telemetría para ver los datos de todas las instancias a la vez. Seleccione el recurso primario, etiquetado (application). Para obtener más información, consulte el tablero de .NET.NET Aspire para combinar telemetría de varios recursos.

Soporte de telemetría del navegador

El panel admite el Protocolo OpenTelemetry (OTLP) sobre HTTP y el uso compartido de recursos entre orígenes (CORS). Estas características desbloquean la capacidad de enviar OpenTelemetry desde aplicaciones del explorador al panel de .NET Aspire.

Por ejemplo, una aplicación de página única (SPA) basada en explorador puede configurar la SDK de JavaScript OpenTelemetry para enviar registros estructurados, seguimientos y métricas creados en el explorador al panel. La telemetría del navegador se muestra junto con la telemetría de server.

página de detalles de seguimiento con telemetría del explorador

Para obtener más información sobre cómo configurar la telemetría del explorador, consulte documentación sobre cómo habilitar la telemetría del explorador.

Host de Aplicación (Orquestación)

El host de la aplicación es una de las características más importantes de de . En .NET.NET Aspire 9, se agregaron varias características nuevas específicas al host de la aplicación.

Esperando dependencias

Si ha seguido junto con .NET.NET Aspire, ya sabe que el proyecto host de la aplicación es donde define el modelo de aplicación. Cree un generador de aplicaciones distribuido, agregue y configure recursos y exprese sus dependencias. Ahora, puede especificar que un recurso debe esperar para otro recurso antes de iniciarse. Esto puede ayudar a evitar errores de conexión durante el inicio iniciando solo los recursos cuando sus dependencias están "listas".

var builder = DistributedApplication.CreateBuilder(args);

var rabbit = builder.AddRabbitMQ("rabbit");

builder.AddProject<Projects.WebApplication1>("api")
       .WithReference(rabbit)
       .WaitFor(rabbit); // Don't start "api" until "rabbit" is ready...

builder.Build().Run();

Cuando se inicia el host de la aplicación, espera a que el recurso de rabbit esté listo antes de iniciar el recurso de api.

Hay dos métodos disponibles para esperar a que un recurso esté disponible:

  • WaitFor: espere a que un recurso esté listo antes de iniciar otro recurso.
  • WaitForCompletion: espere a que se complete un recurso antes de iniciar otro recurso.

Para obtener más información, consulte .NET.NET Aspire host de la aplicación: Esperando recursos.

Comprobaciones de estado de los recursos

La API de WaitFor usa .NET comprobaciones de estado estándar para determinar si un recurso está listo. Pero, ¿qué significa "un recurso listo"? La mejor parte es que el consumidor puede configurar más allá de sus valores predeterminados.

Cuando un recurso no expone ninguna comprobación de estado (sin comprobaciones de estado registradas en la aplicación), el host de la aplicación espera a que el recurso esté en el estado Running antes de iniciar el recurso dependiente.

En el caso de los recursos que exponen puntos de conexión HTTP, puede agregar fácilmente una comprobación de estado que sondee una ruta de acceso específica para una respuesta HTTP 200.

var builder = DistributedApplication.CreateBuilder(args);

var catalogApi = builder.AddContainer("catalog-api", "catalog-api")
                        .WithHttpEndpoint(targetPort: 8080)
                        .WithHttpHealthCheck("/health");

builder.AddProject<Projects.WebApplication1>("store")
       .WithReference(catalogApi.GetEndpoint("http"))
       .WaitFor(catalogApi);

builder.Build().Run();

En el ejemplo anterior se agrega una comprobación de estado al recurso catalog-api. El anfitrión de la aplicación espera a que la comprobación de estado devuelva un estado saludable antes de iniciar el recurso de store. Determina que el recurso está listo cuando el punto de conexión de /health devuelve un código de estado HTTP 200.

Mientras store espera a que catalog-api se vuelvan saludables, los recursos del panel aparecen como:

Esperando un recurso insalubre antes de iniciar

El mecanismo de comprobación de estado del host de la aplicación se basa en la implementación de IHealthChecksBuilder desde el espacio de nombres Microsoft.Extensions.Diagnostics.HealthChecks.

Los datos del informe de comprobaciones de salud, que se muestran en el panel de control.

detalles de comprobación de estado en la vista de detalles del recurso del panel

La creación de una comprobación de estado personalizada es sencilla. Comience definiendo la comprobación de estado y asocie su nombre a los recursos a los que se aplica.

var builder = DistributedApplication.CreateBuilder(args);

var healthyAfter = DateTime.Now.AddSeconds(20);

builder.Services.AddHealthChecks().AddCheck(
    "delay20secs",
    () => DateTime.Now > healthyAfter 
        ? HealthCheckResult.Healthy() 
        : HealthCheckResult.Unhealthy()
    );

var cache = builder.AddRedis("cache")
                   .WithHealthCheck("delay20secs");

builder.AddProject<Projects.MyApp>("myapp")
       .WithReference(cache)
       .WaitFor(cache);

En el ejemplo anterior se agrega una comprobación de estado al recurso de cache, que lo notifica como no saludable durante los primeros 20 segundos después de que el host de la aplicación se inicie. Por lo tanto, el recurso de myapp espera 20 segundos antes de comenzar, garantizando que el recurso de cache esté en buen estado.

Los métodos AddCheck y WithHealthCheck proporcionan un mecanismo sencillo para crear comprobaciones de estado y asociarlos a recursos específicos.

Contenedores persistentes

El host de la aplicación ahora admite contenedores persistentes de. Los contenedores persistentes se desvía de la ciclo de vida típico del contenedor de .NET.NET Aspire aplicaciones orquestadas. Aunque son creados e iniciados (cuando aún no están disponibles) por el orquestador de .NET Aspire, no son destruidos por .NET Aspire.

Esto resulta útil cuando desea mantener el contenedor en ejecución incluso después de que el host de la aplicación se haya detenido.

Importante

Para eliminar estos contenedores, debe detenerlos manualmente mediante el entorno de ejecución del contenedor.

Para definir un IResourceBuilder<ContainerResource> con una duración persistente, llame al método WithLifetime y pase ContainerLifetime.Persistent:

var builder = DistributedApplication.CreateBuilder(args);

var queue = builder.AddRabbitMQ("rabbit")
                   .WithLifetime(ContainerLifetime.Persistent);

builder.AddProject<Projects.WebApplication1>("api")
       .WithReference(queue)
       .WaitFor(queue);

builder.Build().Run();

El panel muestra contenedores persistentes con un icono de anclaje:

contenedores persistentes

Una vez detenido el host de la aplicación, el contenedor seguirá ejecutándose:

Docker escritorio mostrando RabbitMQ.

El mecanismo de persistencia del contenedor intenta identificar cuándo podría querer volver a crear el contenedor. Por ejemplo, si cambia el entorno del contenedor, se reinicia el contenedor para que no sea necesario detener manualmente el contenedor si ha cambiado la configuración de entrada del recurso.

Comandos de recursos

El host de la aplicación admite la adición de comandos personalizados a los recursos. Esto resulta útil cuando desea agregar funcionalidad personalizada que no es compatible de forma nativa con el host de la aplicación. Es probable que haya muchas oportunidades en las que exponer métodos de extensión personalizados en los recursos será útil. La .NET.NET Aspire Community Toolkit podría ser un buen lugar para compartir estas extensiones.

Al definir un comando personalizado, está disponible en el panel como una característica de experiencia del usuario.

Importante

Estos comandos de panel .NET.NET Aspire solo están disponibles al ejecutar el panel localmente. No están disponibles cuando se ejecuta el panel en Azure Container Apps.

Para obtener más información sobre cómo crear comandos de recursos personalizados, consulte Procedimientos: Creación de comandos de recursos personalizados en .NET.NET Aspire.

Redes de contenedores

El host de la aplicación ahora agrega todos los contenedores a una red común denominada default-aspire-network. Esto resulta útil cuando desea comunicarse entre contenedores sin pasar por la red host. Esto también facilita la migración de la "compose" de docker al host de la aplicación, ya que los contenedores pueden comunicarse entre sí usando el nombre del contenedor.

Modelo de eventos

El modelo de eventos permite a los desarrolladores enlazar el ciclo de vida de la aplicación y los recursos. Esto resulta útil para ejecutar código personalizado en puntos específicos del ciclo de vida de la aplicación. Hay varias maneras de suscribirse a eventos, incluidos los eventos globales y los eventos por recurso.

Eventos globales:

  • BeforeStartEvent: evento que se desencadena antes de que se inicie la aplicación. Este es el último lugar en el que se observan los cambios en el modelo de aplicación. Esto se ejecuta en los modos "Ejecutar" y "Publicar". Se trata de un evento de bloqueo, lo que significa que la aplicación no se inicia hasta que se hayan completado todos los controladores.
  • AfterResourcesCreatedEvent: evento que se desencadena después de crear los recursos. Esto solo se ejecuta en modo de ejecución.
  • AfterEndpointsAllocatedEvent: evento que se desencadena después de asignar los puntos de conexión para todos los recursos. Esto solo se ejecuta en modo de ejecución.

Los eventos globales son análogos a los eventos del ciclo de vida del host de la aplicación. Para obtener más información, consulte Ciclos de vida del host de la aplicación.

Eventos por recurso:

  • BeforeResourceStartedEvent: evento que se desencadena antes de que se inicie un único recurso. Esto solo se ejecuta en modo de ejecución. Este es un evento de bloqueo, lo que significa que el recurso no se inicia hasta que se hayan completado todos los manejadores.
  • ConnectionStringAvailableEvent: evento que se desencadena cuando hay una cadena de conexión disponible para un recurso. Esto solo se ejecuta en modo de ejecución.
  • ResourceReadyEvent: evento que se desencadena cuando un recurso está listo para usarse. Esto solo se ejecuta en modo de ejecución.

Para obtener más información, consulte sobre la gestión de eventos en .NET.NET Aspire.

Integraciones

.NET .NET Aspire sigue agregando integraciones que facilitan la introducción a sus servicios y herramientas favoritos. Para obtener más información, consulte .NET.NET Aspire integrations overview.

información de Redis

Soporte para Redis Insights está disponible en un recurso de Redis.

var builder = DistributedApplication.CreateBuilder(args);

builder.AddRedis("redis")
       .WithRedisInsight(); // Starts a Redis Insight container image
                            // that is pre-configured to work with the
                            // Redis instance.

El método de extensión WithRedisInsight se puede aplicar a varios recursos Redis y cada uno estará visible en el panel de Redis Insight.

panel de Redis Insight en el que se muestran varias instancias de Redis

Para obtener más información, consulte Agregar Redis recurso con Redis Insights.

OpenAI (versión preliminar)

A partir de .NET Aspire 9, está disponible una integración adicional de OpenAI, que permite usar directamente la última versión oficial de la biblioteca .NET OpenAI. La integración de client registra el OpenAIClient como un servicio singleton en la colección de servicios. El client se puede usar para interactuar con la API de OpenAIREST.

Además, se ha mejorado la de integración de ya disponible para proporcionar una manera flexible de configurar un para un servicio o una API dedicada de con el nuevo método de construcción de . En el ejemplo siguiente se detecta si la cadena de conexión es para un servicio AzureAzure AI OpenAI y registra automáticamente la instancia de OpenAIClient más adecuada.

builder.AddOpenAIClientFromConfiguration("openai");

Por ejemplo, si la conexión openai se pareciera a Endpoint=https://{account}.azure.com;Key={key}; deduciría que puede registrar un Azure AI OpenAIclient gracias al nombre de dominio. De lo contrario, se usaría un OpenAIClient común.

Lea Azureagnóstico de client resolución para obtener más detalles.

MongoDB

Se ha agregado compatibilidad para especificar el nombre de usuario y la contraseña de MongoDB al usar el método de extensión AddMongoDB(IDistributedApplicationBuilder, String, Nullable<Int32>, IResourceBuilder<ParameterResource>, IResourceBuilder<ParameterResource>). Si no se especifica, se genera un nombre de usuario y una contraseña aleatorios, pero se puede especificar manualmente mediante recursos de parámetros.

var builder = DistributedApplication.CreateBuilder(args);

var username = builder.AddParameter("mongousername");
var password = builder.AddParameter("mongopassword", secret: true);

var db = builder.AddMongo("db", username, password);

Mejoras importantes Azure

En las secciones siguientes se describen las mejoras en Azure incluidas en .NET Aspire 9. Para obtener una lista completa de todos los cambios importantes, consulte Cambios importantes en .NET.NET Aspire 9.

personalización de recursos de Azure

En .NET Aspire 8, la personalización de los recursos de Azure se marcó como experimental porque las bibliotecas de Azure.Provisioning subyacentes eran nuevas y recopilaban comentarios antes de que se pudieran marcar como estables. En .NET.NET Aspire 9 estas API se actualizaron y quitan el atributo experimental.

Azure cambio disruptivo de nomenclatura de recursos

Como parte de la actualización a las bibliotecas de Azure.Provisioning, el esquema de nomenclatura predeterminado para los recursos de Azure se actualizó con una mejor compatibilidad con varias directivas de nomenclatura. Sin embargo, esta actualización dio lugar a un cambio en el nombre de los recursos. La nueva directiva de nomenclatura puede dar lugar a que los recursos de Azure existentes se abandonen y se creen nuevos recursos de Azure, después de actualizar la aplicación de .NET Aspire de la versión 8 a la 9. Para seguir usando las mismas directivas de nomenclatura de .NET.NET Aspire 8, puede agregar el código siguiente a appHost Program.cs:

var builder = DistributedApplication.CreateBuilder(args);

builder.Services.Configure<AzureProvisioningOptions>(options =>
{
    options.ProvisioningBuildOptions.InfrastructureResolvers.Insert(0, new AspireV8ResourceNamePropertyResolver());
});

Azure SQL, PostgreSQLy actualización de Redis

Azure SQL, PostgreSQLy Redis recursos son diferentes de otros recursos de Azure porque hay recursos de contenedor locales para estas tecnologías. En .NET Aspire 8, para crear estos recursos Azure, necesitabas comenzar con un recurso de contenedor local y luego usar "As" o "PublishAs" para convertirlo en un recurso de Azure. Este diseño introdujo problemas y no encajaba con otras API.

Por ejemplo, puede tener este código en .NET.NET Aspire 8:

var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
                 .PublishAsAzureSqlDatabase();

var pgsql = builder.AddPostgres("pgsql")
                   .PublishAsAzurePostgresFlexibleServer();

var cache = builder.AddRedis("cache")
                   .PublishAsAzureSqlDatabase();

En .NET.NET Aspire 9 estas API se marcaron como obsoletas y se implementó un nuevo patrón de API:

var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddAzureSqlServer("sql")
                 .RunAsContainer();

var pgsql = builder.AddAzurePostgresFlexibleServer("pgsql")
                   .RunAsContainer();

var cache = builder.AddAzureRedis("cache")
                   .RunAsContainer();
ID de Microsoft Entra de forma predeterminada

Para que las aplicaciones de .NET Aspire sean más seguras, Azure Database for PostgreSQL y los recursos de Azure Cache for Redis se actualizaron para usar el identificador entra de Microsoft de forma predeterminada. Esto requiere cambios en las aplicaciones que necesitan conectarse a estos recursos. Consulte lo siguiente para actualizar las aplicaciones para usar el identificador de Microsoft Entra para conectarse a estos recursos:

En los ejemplos siguientes se muestra cómo configurar la aplicación para conectarse a los recursos de Azure mediante el identificador de Microsoft Entra:

Si necesita usar la autenticación de contraseña o clave de acceso (no recomendada), puede participar con el código siguiente:

var builder = DistributedApplication.CreateBuilder(args);

var pgsql = builder.AddAzurePostgresFlexibleServer("pgsql")
                   .WithPasswordAuthentication();

var cache = builder.AddAzureRedis("cache")
                   .WithAccessKeyAuthentication();

Compatibilidad con funciones de Azure (versión preliminar)

La compatibilidad con Azure Functions es una de las funciones más solicitadas en el registro de problemas de .NET.NET Aspire, y nos complace presentar soporte preliminar para ella en esta versión. Para demostrar esta compatibilidad, vamos a usar .NET.NET Aspire para crear e implementar un webhook.

Para empezar, cree un nuevo proyecto de Azure Functions mediante el cuadro de diálogo Visual Studio Nuevo Proyecto. Cuando se le solicite, active la casilla Inscribirse en Aspire orquestación al crear el proyecto.

Crear nuevo proyecto de Funciones de .NET AspireAzure.

En el proyecto host de la aplicación, observe que hay un PackageReference en el nuevo 📦Aspire.Hosting.Azure.Funciones paquete NuGet.

<ItemGroup>
    <PackageReference Include="Aspire.Hosting.AppHost" Version="9.0.0" />
    <PackageReference Include="Aspire.Hosting.Azure.Functions" Version="9.0.0" />
</ItemGroup>

Este paquete proporciona una API de AddAzureFunctionsProject<TProject>(IDistributedApplicationBuilder, String) que se puede invocar en el host de la aplicación para configurar proyectos Azure Functions dentro de un host de .NET Aspire:

var builder = DistributedApplication.CreateBuilder(args);

builder.AddAzureFunctionsProject<Projects.PigLatinApp>("piglatinapp");

builder.Build().Run();

En este ejemplo, el webhook es responsable de traducir una cadena de entrada a Pig Latin. Actualice el contenido del desencadenador con el código siguiente:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using System.Text;
using FromBodyAttribute = Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute;

namespace PigLatinApp;

public class Function1(ILogger<Function1> logger)
{
    public record InputText(string Value);
    public record PigLatinText(string Value);

    [Function("Function1")]
    public IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
        [FromBody] InputText inputText)
    {
        logger.LogInformation("C# HTTP trigger function processed a request.");

        var result = TranslateToPigLatin(inputText.Value);

        return new OkObjectResult(new PigLatinText(result));
    }

    private static string TranslateToPigLatin(string input)
    {
        if (string.IsNullOrEmpty(input))
        {
            return input;
        }

        var words = input.Split(' ');
        StringBuilder pigLatin = new();

        foreach (string word in words)
        {
            if (IsVowel(word[0]))
            {
                pigLatin.Append(word + "yay ");
            }
            else
            {
                int vowelIndex = FindFirstVowelIndex(word);
                if (vowelIndex is -1)
                {
                    pigLatin.Append(word + "ay ");
                }
                else
                {
                    pigLatin.Append(
                        word.Substring(vowelIndex) + word.Substring(0, vowelIndex) + "ay ");
                }
            }
        }

        return pigLatin.ToString().Trim();
    }

    private static int FindFirstVowelIndex(string word)
    {
        for (var i = 0; i < word.Length; i++)
        {
            if (IsVowel(word[i]))
            {
                return i;
            }
        }
        return -1;
    }

    private static bool IsVowel(char c) =>
        char.ToLower(c) is 'a' or 'e' or 'i' or 'o' or 'u';
}

Establezca un punto de interrupción en la primera línea logger.LogInformation del método Run y presione F5 para iniciar el host de Functions. Una vez que se inicie el tablero de control de .NET.NET Aspire, observe usted lo siguiente:

Captura de pantalla de la .NET Aspire que se ejecuta con una aplicación de funciones de Azure.

.NET .NET Aspire tiene:

  • Se ha configurado un recurso de almacenamiento emulado Azure que se usará para la contabilidad por parte del host.
  • Inicie el host de Functions localmente con el destino como proyecto de Functions registrado.
  • Cablee el puerto definido en launchSettings.json del proyecto de funciones para escuchar.

Utiliza el HTTP client de tu elección para enviar una solicitud al desencadenador y observar en el depurador las entradas vinculadas desde el cuerpo de la solicitud.

curl --request POST \
  --url http://localhost:7282/api/Function1 \
  --header 'Content-Type: application/json' \
  --data '{
  "value": "Welcome to Azure Functions"
}'

Captura de pantalla del panel .NET Aspire: Depuración de una aplicación de funciones de Azure.

Ahora estás listo para implementar nuestra aplicación en Azure Container Apps (ACA). La implementación depende actualmente de las compilaciones en versión preliminar de los paquetes de Azure Functions Worker y Worker SDK. Si es necesario, actualice las versiones a las que se hace referencia en el proyecto de Functions:

<ItemGroup>
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.0.0-preview2" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.0-preview2" />
</ItemGroup>

También debe exponer un punto de conexión público para nuestro proyecto de Azure Functions para que las solicitudes se puedan enviar a nuestro desencadenador HTTP:

builder.AddAzureFunctionsProject<Projects.PigLatinApp>("piglatinapp")
       .WithExternalHttpEndpoints();

Para implementar la aplicación con la CLI de azd, primero debe obtener la versión más reciente. Para instalar la versión más reciente, verá una advertencia si la versión no está actualizada. Siga las instrucciones para actualizar a la versión más reciente.

Una vez instalado, vaya a la carpeta que contiene el proyecto host de la aplicación y ejecute azd init:

$ azd init

Initializing an app to run on Azure (azd init)

? How do you want to initialize your app? Use code in the current directory

  (✓) Done: Scanning app code in current directory

Detected services:

  .NET (Aspire)
  Detected in: ./PigLatinApp/PigLatinApp.AppHost/PigLatinApp.AppHost.csproj

azd will generate the files necessary to host your app on Azure using Azure Container Apps.

? Select an option Confirm and continue initializing my app
? Enter a new environment name: azfunc-piglatin

Generating files to run your app on Azure:

  (✓) Done: Generating ./azure.yaml
  (✓) Done: Generating ./next-steps.md

SUCCESS: Your app is ready for the cloud!

A continuación, implemente la aplicación mediante la ejecución de azd up:

$ azd up 
? Select an Azure Subscription to use: 130. [redacted]
? Select an Azure location to use: 50. (US) West US 2 (westus2)

Packaging services (azd package)


Provisioning Azure resources (azd provision)
Provisioning Azure resources can take some time.

Subscription: [redacted]
Location: West US 2

  You can view detailed progress in the Azure Portal:
  [redacted]

  (✓) Done: Resource group: rg-azfunc-piglatin (967ms)
  (✓) Done: Container Registry: [redacted] (13.316s)
  (✓) Done: Log Analytics workspace: [redacted] (16.467s)
  (✓) Done: Container Apps Environment: [redacted] (1m35.531s)
  (✓) Done: Storage account: [redacted] (21.37s)

Deploying services (azd deploy)

  (✓) Done: Deploying service piglatinapp
  - Endpoint: {{endpoint-url}}

  Aspire Dashboard: {{dashboard-url}}

Por último, pruebe la aplicación de funciones implementada utilizando su herramienta clientHTTP favorita.

curl --request POST \
  --url {{endpoint-url}}/api/Function1 \
  --header 'Content-Type: application/json' \
  --data '{
  "value": "Welcome to Azure Functions"
}'

La compatibilidad de Azure Functions en .NET Aspire sigue en fase de vista previa y admite un conjunto limitado de desencadenadores, entre los que se incluyen:

Para obtener más información, consulte la integración oficial de .NET AspireAzure Functions (versión preliminar).

Personalización de Azure Container Apps

Una de las características más solicitadas es la capacidad de personalizar el Azure Container Apps que crea el host de la aplicación sin tocar Bicep. Esto es posible mediante el uso de las API de PublishAsAzureContainerApp<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure,ContainerApp>) y PublishAsAzureContainerApp<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure,ContainerApp>) en el espacio de nombres Aspire.Hosting.Azure.AppContainers. Estos métodos personalizan la definición de aplicación contenedora Azure que crea el host de la aplicación.

Agregue la referencia de paquete al archivo del proyecto:

<ItemGroup>
  <PackageReference Include="Aspire.Hosting.Azure.AppContainers"
                    Version="9.0.0" />
</ItemGroup>

En el ejemplo siguiente se muestra cómo escalar una aplicación contenedora de Azure a cero (0) réplicas:

var builder = DistributedApplication.CreateBuilder(args);

var db = builder.AddAzurePostgresFlexibleServer("pg")
                .RunAsContainer()
                .AddDatabase("db");

// Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#pragma warning disable AZPROVISION001

builder.AddProject<Projects.WebApplication1>("api")
       .WithReference(db)
       .PublishAsAzureContainerApp((module, containerApp) =>
       {
           // Scale to 0
           containerApp.Template.Value!.Scale.Value!.MinReplicas = 0;
       });

#pragma warning restore AZPROVISION001

builder.Build().Run();

En el ejemplo de código anterior se aplaza la generación de la definición de Azure Container App al host de la aplicación. Esto le permite personalizar la definición de aplicación contenedora de Azure sin necesidad de ejecutar azd infra synth y modificar de forma no segura los archivos bicep generados.

Consulte también