Partilhar via


Visão geral da orquestração .NET.NET Aspire

.NET .NET Aspire fornece APIs para expressar recursos e dependências em seu aplicativo distribuído. Além destas APIs, há uma ferramenta que permite vários cenários atraentes. O orquestrador é destinado para fins de desenvolvimento local e não é suportado em ambientes de produção.

Antes de continuar, considere algumas terminologias comuns usadas em .NET.NET Aspire:

  • Modelo de aplicativo: uma coleção de recursos que compõem seu aplicativo distribuído (DistributedApplication), definido dentro do namespace Aspire.Hosting.ApplicationModel. Para obter uma definição mais formal, consulte Definir o modelo de aplicativo.
  • Projeto Host/Orquestrador de aplicação: O projeto .NET que orquestra a modelo de aplicação, chamado, por convenção, com o sufixo *.AppHost.
  • Recurso: Um recurso é uma parte dependente de uma aplicação, como um .NET projeto, contêiner, executável, base de dados, cache ou serviço de nuvem. Ele representa qualquer parte do aplicativo que pode ser gerenciada ou referenciada.
  • Integração: uma integração é um pacote NuGet para o hospedeiro de aplicação que modela um recurso ou um pacote que configura um cliente para uso numa aplicação consumidora. Para obter mais informações, consulte .NET.NET Aspire visão geral das integrações.
  • Referência: Uma referência define uma conexão entre recursos, expressa como uma dependência usando a API WithReference. Para obter mais informações, consulte Recursos de referência ou Referenciar recursos existentes.

Observação

A orquestração do .NET.NET Aspire é projetada para melhorar a sua experiência de desenvolvimento local, simplificando a gestão da configuração e das interconexões da sua aplicação cloud-nativa. Embora seja uma ferramenta inestimável para o desenvolvimento, não se destina a substituir sistemas de ambiente de produção como Kubernetes, que são projetados especificamente para se destacar nesse contexto.

Definir o modelo de aplicativo

.NET .NET Aspire permite que você crie, provisione, implante, configure, teste, execute e observe seus aplicativos distribuídos sem problemas. Todos esses recursos são alcançados por meio da utilização de um modelo de aplicativo que descreve os recursos em sua solução .NET.NET Aspire e seus relacionamentos. Esses recursos abrangem projetos, executáveis, contêineres e serviços externos e recursos de nuvem dos quais seu aplicativo depende. Dentro de cada solução .NET.NET Aspire, há um projeto de host de aplicativo designado, onde o modelo de aplicativo é definido com precisão usando métodos disponíveis no IDistributedApplicationBuilder. Este construtor é obtido invocando DistributedApplication.CreateBuilder.

// Create a new app model builder
var builder = DistributedApplication.CreateBuilder(args);

// TODO:
//   Add resources to the app model
//   Express dependencies between resources

builder.Build().Run();

Projeto de host de aplicativo

O projeto host do aplicativo lida com a execução de todos os projetos que fazem parte do projeto .NET.NET Aspire. Em outras palavras, ele é responsável por orquestrar todos os aplicativos dentro do modelo de aplicativo. O projeto em si é um projeto executável .NET que faz referência ao 📦Aspire. Hosting.AppHost pacote NuGet, define a propriedade IsAspireHost como truee faz referência ao SDK .NET.NET Aspire:

<Project Sdk="Microsoft.NET.Sdk">

    <Sdk Name="Aspire.AppHost.Sdk" Version="9.1.0" />
    
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net9.0</TargetFramework>
        <IsAspireHost>true</IsAspireHost>
        <!-- Omitted for brevity -->
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Aspire.Hosting.AppHost" Version="9.1.0" />
    </ItemGroup>

    <!-- Omitted for brevity -->

</Project>

O código a seguir descreve um host de aplicativo Program com duas referências de projeto e um cache Redis.

var builder = DistributedApplication.CreateBuilder(args);

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

var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");

builder.AddProject<Projects.AspireApp_Web>("webfrontend")
       .WithExternalHttpEndpoints()
       .WithReference(cache)
       .WaitFor(cache)
       .WithReference(apiService)
       .WaitFor(apiService);

builder.Build().Run();

O código anterior:

  • Cria um novo construtor de modelos de aplicativo usando o método CreateBuilder.
  • Adiciona um recurso Rediscache chamado "cache" usando o método AddRedis.
  • Adiciona um recurso de projeto chamado "apiservice" usando o método AddProject.
  • Adiciona um recurso de projeto chamado "webfrontend" usando o método AddProject.
    • Especifica que o projeto tem endpoints HTTP externos usando o método WithExternalHttpEndpoints.
    • Adiciona uma referência ao recurso cache e aguarda que ele esteja pronto usando os métodos WithReference e WaitFor.
    • Adiciona uma referência ao recurso apiservice e aguarda que ele esteja pronto usando os métodos WithReference e WaitFor.
  • Cria e executa o modelo de aplicativo usando os métodos Build e Run.

O código de exemplo usa a integração de hospedagem .NET AspireRedis.

Para ajudar a visualizar a relação entre o projeto de host do aplicativo e os recursos que ele descreve, considere o diagrama a seguir:

A relação entre os projetos no modelo .NET.NET Aspire Starter Application.

Cada recurso deve ter um nome exclusivo. Este diagrama mostra cada recurso e as relações entre eles. O recurso de contêiner é chamado de "cache" e os recursos do projeto são chamados de "apiservice" e "webfrontend". O projeto de front-end da Web faz referência aos projetos de serviço de cache e API. Quando você está expressando referências dessa maneira, o projeto de frontend da Web está dizendo que depende desses dois recursos, o "cache" e o "apiservice", respectivamente.

Tipos de recursos incorporados

.NET .NET Aspire projetos são constituídos por um conjunto de recursos. Os principais tipos de recursos base no 📦Aspire.Hosting.AppHost pacote NuGet estão descritos na tabela abaixo.

Método Tipo de recurso Descrição
AddProject ProjectResource Um projeto .NET, por exemplo, um aplicativo Web ASP.NET Core.
AddContainer ContainerResource Uma imagem de contêiner, como uma imagem Docker.
AddExecutable ExecutableResource Um arquivo executável, como um aplicativo Node.js.
AddParameter ParameterResource Um recurso de parâmetro que pode ser usado para expressar parâmetros externos.

Os recursos de projeto representam .NET projetos que fazem parte do modelo de aplicativo. Quando você adiciona uma referência de projeto ao projeto de host do aplicativo, o SDK do .NET.NET Aspire gera um tipo no namespace Projects para cada projeto referenciado. Para obter mais informações, consulte .NET.NET Aspire SDK: Referências de projeto.

Para adicionar um projeto ao modelo de aplicativo, use o método AddProject:

var builder = DistributedApplication.CreateBuilder(args);

// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");

Os projetos podem ser replicados e dimensionados adicionando várias instâncias do mesmo projeto ao modelo de aplicativo. Para configurar réplicas, use o método WithReplicas:

var builder = DistributedApplication.CreateBuilder(args);

// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
                        .WithReplicas(3);

O código anterior adiciona três réplicas do recurso de projeto "apiservice" ao modelo de aplicativo. Para mais informações, consulte o painel de controlo .NET.NET Aspire: Réplicas de recursos.

Configurar início explícito de recursos

Os recursos de projeto, executáveis e contêineres são iniciados automaticamente com seu aplicativo distribuído por padrão. Um recurso pode ser configurado para aguardar uma instrução de inicialização explícita com o método WithExplicitStart. Um recurso configurado com WithExplicitStart é inicializado com KnownResourceStates.NotStarted.

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");

builder.AddProject<Projects.AspireApp_DbMigration>("dbmigration")
       .WithReference(postgresdb)
       .WithExplicitStart();

No código anterior, o recurso "dbmigration" é configurado para não iniciar automaticamente com o aplicativo distribuído.

Os recursos com início explícito podem ser iniciados a partir do painel .NET.NET Aspire clicando no comando "Iniciar". Para obter mais informações, consulte o painel de controlo .NET.NET Aspire: Parar ou Começar um recurso.

Recursos de referência

Uma referência representa uma dependência entre recursos. Por exemplo, você provavelmente pode imaginar um cenário em que um frontend da Web depende de um cache Redis. Considere o seguinte exemplo de host de aplicativo Program código C#:

var builder = DistributedApplication.CreateBuilder(args);

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

builder.AddProject<Projects.AspireApp_Web>("webfrontend")
       .WithReference(cache);

O recurso de projeto "webfrontend" usa WithReference para adicionar uma dependência no recurso de contêiner "cache". Essas dependências podem representar cadeias de conexão ou informações sobre descoberta de serviço. No exemplo anterior, uma variável de ambiente é injetada no recurso "webfrontend" com o nome ConnectionStrings__cache. Essa variável de ambiente contém uma cadeia de conexão que o webfrontend utiliza para se conectar a Redis através da integração .NET AspireRedis, por exemplo, ConnectionStrings__cache="localhost:62354".

À espera de recursos

Em alguns casos, convém aguardar que um recurso esteja pronto antes de iniciar outro recurso. Por exemplo, talvez você queira aguardar que um banco de dados esteja pronto antes de iniciar uma API que depende dele. Para expressar essa dependência, use o método WaitFor:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");

builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
       .WithReference(postgresdb)
       .WaitFor(postgresdb);

No código anterior, o recurso de projeto "apiservice" aguarda que o recurso de banco de dados "postgresdb" insira o KnownResourceStates.Running. O código de exemplo mostra a integração .NET AspirePostgreSQL, mas o mesmo padrão pode ser aplicado a outros recursos.

Outros casos podem justificar a espera pelo término de um recurso, seja KnownResourceStates.Exited ou KnownResourceStates.Finished, antes de iniciar o recurso dependente. Para aguardar a conclusão de um recurso, use o método WaitForCompletion:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");

var migration = builder.AddProject<Projects.AspireApp_Migration>("migration")
                       .WithReference(postgresdb)
                       .WaitFor(postgresdb);

builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
       .WithReference(postgresdb)
       .WaitForCompletion(migration);

No código anterior, o recurso de projeto "apiservice" aguarda que o recurso de projeto "migração" seja executado até a conclusão antes de iniciar. O recurso do projeto "migração" aguarda que o recurso de banco de dados "postgresdb" entre no estado KnownResourceStates.Running. Isso pode ser útil em cenários em que você deseja executar uma migração de banco de dados antes de iniciar o serviço de API, por exemplo.

Forçando a ativação do recurso no painel

A espera por um recurso pode ser ignorada usando o comando "Iniciar" no painel. Clicar em "Iniciar" em um recurso em espera no painel instrui-o a iniciar imediatamente sem esperar que o recurso esteja íntegro ou concluído. Isso pode ser útil quando você deseja testar um recurso imediatamente e não quer esperar que o aplicativo esteja no estado certo.

APIs para adicionar e expressar recursos

.NET .NET Aspire integrações de hospedagem e integrações de cliente são entregues como pacotes NuGet, mas servem a propósitos diferentes. Enquanto as integrações de cliente fornecem configuração de biblioteca de cliente para consumir aplicativos fora do escopo do host do aplicativo, as integrações de hospedagem fornecem APIs para expressar recursos e dependências dentro do host do aplicativo. Para obter mais informações, consulte Visão geral de integrações .NET.NET Aspire: Responsabilidades de integração.

Recursos de contêiner expressos

Para expressar um ContainerResource adicione-o a uma instância IDistributedApplicationBuilder chamando o método AddContainer:

var builder = DistributedApplication.CreateBuilder(args);

var ollama = builder.AddContainer("ollama", "ollama/ollama")
    .WithBindMount("ollama", "/root/.ollama")
    .WithBindMount("./ollamaconfig", "/usr/config")
    .WithHttpEndpoint(port: 11434, targetPort: 11434, name: "ollama")
    .WithEntrypoint("/usr/config/entrypoint.sh")
    .WithContainerRuntimeArgs("--gpus=all");

Para obter mais informações, consulte suporte a GPU no Docker Desktop.

O código anterior adiciona um recurso de contêiner chamado "ollama" com a imagem ollama/ollama. O recurso de contentor é configurado com múltiplos pontos de montagem, um ponto de extremidade HTTP nomeado, um ponto de entrada que corresponde ao script de shell Unix, e argumentos para execução do contentor definidos pelo método WithContainerRuntimeArgs.

Personalizar recursos de contêiner

Todas as ContainerResource subclasses podem ser personalizadas para atender às suas necessidades específicas. Isso pode ser útil ao usar uma integração de hospedagem que modela um recurso de contêiner, mas requer modificações. Quando você tem um IResourceBuilder<ContainerResource> pode encadear chamadas para qualquer uma das APIs disponíveis para modificar o recurso de contêiner. Os recursos do contentor .NET.NET Aspire geralmente apontam para tags fixadas, mas talvez prefira usar a tag latest em alternativa.

Para ajudar a exemplificar isto, imagine um cenário em que está a utilizar a integração .NET AspireRedis. Se a integração de Redis depender da tag 7.4 e você quiser usar a tag latest, poderá encadear uma chamada para a API WithImageTag:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache")
                   .WithImageTag("latest");

// Instead of using the "7.4" tag, the "cache" 
// container resource now uses the "latest" tag.

Para obter mais informações e APIs adicionais disponíveis, consulte ContainerResourceBuilderExtensions.

Ciclo de vida do recurso de contêiner

Quando o host do aplicativo é executado, o ContainerResource é usado para determinar qual imagem de contêiner criar e iniciar. Na prática, .NET Aspire executa o contentor utilizando a imagem de contentor definida, delegando as chamadas ao runtime de contentor compatível com OCI apropriado, seja Docker ou Podman. Os seguintes comandos são usados:

Primeiro, o contêiner é criado usando o comando docker container create. Em seguida, o contêiner é iniciado usando o comando docker container start.

Esses comandos são usados em vez de docker run para gerenciar redes, volumes e portas de contêineres conectados. Chamar esses comandos nessa ordem permite que qualquer IP (configuração de rede) já esteja presente na inicialização inicial.

Além dos tipos de recursos básicos, ProjectResource, ContainerResourcee ExecutableResource, .NET.NET Aspire fornece métodos de extensão para adicionar recursos comuns ao seu modelo de aplicativo. Para obter mais informações, consulte integrações de hospedagem.

Tempo de vida do recurso do contêiner

Por padrão, os recursos dos contêineres usam o tempo de vida sessão do contêiner. Isso significa que toda vez que o processo de host do aplicativo é iniciado, o contêiner é criado e iniciado. Quando o host do aplicativo para, o contêiner é interrompido e removido. Os recursos de contêiner podem aderir a um tempo de vida persistente para evitar reinicializações desnecessárias e usar o estado persistente do contêiner. Para conseguir isso, encadeie uma chamada à API ContainerResourceBuilderExtensions.WithLifetime e passe ContainerLifetime.Persistent:

var builder = DistributedApplication.CreateBuilder(args);

var ollama = builder.AddContainer("ollama", "ollama/ollama")
    .WithLifetime(ContainerLifetime.Persistent);

O código anterior adiciona um recurso de contêiner chamado "ollama" com a imagem "ollama/ollama" e um tempo de vida persistente.

Referências da cadeia de conexão e do ponto de extremidade

É comum expressar dependências entre os recursos do projeto. Considere o seguinte código de exemplo:

var builder = DistributedApplication.CreateBuilder(args);

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

var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");

builder.AddProject<Projects.AspireApp_Web>("webfrontend")
       .WithReference(cache)
       .WithReference(apiservice);

As referências de projeto a projeto são tratadas de forma diferente dos recursos que têm cadeias de conexão bem definidas. Em vez de se injetar a cadeia de conexão no recurso "webfrontend", são injetadas variáveis de ambiente para suportar a descoberta de serviços.

Método Variável de ambiente
WithReference(cache) ConnectionStrings__cache="localhost:62354"
WithReference(apiservice) services__apiservice__http__0="http://localhost:5455"
services__apiservice__https__0="https://localhost:7356"

Adicionar uma referência ao projeto "apiservice" resulta em variáveis de ambiente de descoberta de serviço sendo adicionadas ao frontend. Isso ocorre porque, normalmente, a comunicação entre projetos ocorre por HTTP/gRPC. Para obter mais informações, consulte .NET.NET Aspire a descoberta de serviços.

Para obter endpoints específicos de um ContainerResource ou de um ExecutableResource, utilize uma das APIs de endpoint seguintes:

Em seguida, chame a API GetEndpoint para obter o ponto de extremidade que pode ser usado para fazer referência ao ponto de extremidade no método WithReference:

var builder = DistributedApplication.CreateBuilder(args);

var customContainer = builder.AddContainer("myapp", "mycustomcontainer")
                             .WithHttpEndpoint(port: 9043, name: "endpoint");

var endpoint = customContainer.GetEndpoint("endpoint");

var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
                        .WithReference(endpoint);
Método Variável de ambiente
WithReference(endpoint) services__myapp__endpoint__0=https://localhost:9043

O parâmetro port é a porta na qual o contêiner está escutando. Para obter mais informações sobre portas de contêiner, consulte Portas de contêiner. Para obter mais informações sobre a descoberta de serviços, consulte .NET.NET Aspire descoberta de serviços.

Formato da variável de ambiente para o ponto final do serviço

Na seção anterior, o método WithReference é usado para expressar dependências entre recursos. Quando os pontos de extremidade de serviço resultam em variáveis de ambiente sendo injetadas no recurso dependente, o formato pode não ser óbvio. Esta seção fornece detalhes sobre esse formato.

Quando um recurso depende de outro recurso, o host do aplicativo injeta variáveis de ambiente no recurso dependente. Essas variáveis de ambiente configuram o recurso dependente para se conectar ao recurso do qual ele depende. O formato das variáveis de ambiente é específico para .NET.NET Aspire e expressa pontos de extremidade de serviço de forma compatível com Service Discovery.

Os nomes das variáveis de ambiente do ponto de extremidade do serviço são prefixados com services__ (sublinhado duplo), depois o nome do serviço, o nome do ponto de extremidade e, finalmente, o índice. O índice suporta vários endpoints para um único serviço, começando com 0 para o primeiro endpoint e incrementando para cada endpoint.

Considere os seguintes exemplos de variáveis de ambiente:

services__apiservice__http__0

A variável de ambiente anterior expressa o primeiro ponto de extremidade HTTP para o serviço apiservice. O valor da variável de ambiente é a URL do ponto de extremidade do serviço. Um ponto de extremidade nomeado pode ser expresso da seguinte forma:

services__apiservice__myendpoint__0

No exemplo anterior, o serviço apiservice tem um ponto de extremidade nomeado chamado myendpoint. O valor da variável de ambiente é a URL do ponto de extremidade do serviço.

Referenciar recursos existentes

Algumas situações garantem que você faça referência a um recurso existente, talvez um que seja implantado em um provedor de nuvem. Por exemplo, talvez você queira fazer referência a um banco de dados Azure. Nesse caso, confiaria no contexto de execução para determinar dinamicamente se o host do aplicativo está a ser executado no modo de "execução" ou no modo de "publicação". Se você estiver executando localmente e quiser confiar em um recurso de nuvem, poderá usar a propriedade IsRunMode para adicionar condicionalmente a referência. Em vez disso, você pode optar por criar o recurso no modo de publicação. Algumas integrações de hospedagem suportam fornecer diretamente uma cadeia de conexão, que pode ser utilizada para referenciar um recurso existente.

Da mesma forma, pode haver casos de uso em que você deseja integrar .NET.NET Aspire em uma solução existente. Uma abordagem comum é adicionar o projeto de host de aplicativo .NET.NET Aspire a uma solução existente. No host do aplicativo, você expressa dependências adicionando referências de projeto ao host do aplicativo e criando o modelo de aplicativo. Por exemplo, um projeto pode depender de outro. Essas dependências são expressas usando o método WithReference. Para obter mais informações, consulte Adicionar .NET Aspire a um aplicativo .NET existente.

Ciclos de vida do host do aplicativo

O host do aplicativo .NET.NET Aspire expõe vários ciclos de vida aos quais você pode se conectar implementando a interface IDistributedApplicationLifecycleHook. Os seguintes métodos de ciclo de vida estão disponíveis:

Encomenda Método Descrição
1 BeforeStartAsync É executado antes que o aplicativo distribuído seja iniciado.
2 AfterEndpointsAllocatedAsync É executado depois que o orquestrador aloca pontos de extremidade para recursos no modelo de aplicativo.
3 AfterResourcesCreatedAsync Executa depois que o recurso foi criado pelo orquestrador.

Embora o host do aplicativo forneça ganchos de ciclo de vida, convém registrar eventos personalizados. Para obter mais informações, consulte Eventos em .NET.NET Aspire.

Registrar um gancho de ciclo de vida

Para registrar um gancho de ciclo de vida, implemente a interface IDistributedApplicationLifecycleHook e registre o gancho com o host do aplicativo usando a API AddLifecycleHook:

using Aspire.Hosting.Lifecycle;
using Microsoft.Extensions.Logging;

var builder = DistributedApplication.CreateBuilder(args);

builder.Services.AddLifecycleHook<LifecycleLogger>();

builder.Build().Run();

internal sealed class LifecycleLogger(ILogger<LifecycleLogger> logger)
    : IDistributedApplicationLifecycleHook
{
    public Task BeforeStartAsync(
        DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
    {
        logger.LogInformation("BeforeStartAsync");
        return Task.CompletedTask;
    }

    public Task AfterEndpointsAllocatedAsync(
        DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
    {
        logger.LogInformation("AfterEndpointsAllocatedAsync");
        return Task.CompletedTask;
    }

    public Task AfterResourcesCreatedAsync(
        DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
    {
        logger.LogInformation("AfterResourcesCreatedAsync");
        return Task.CompletedTask;
    }
}

O código anterior:

Quando este host da aplicação é executado, o gancho do ciclo de vida é acionado para cada evento. A seguinte saída é gerada:

info: LifecycleLogger[0]
      BeforeStartAsync
info: Aspire.Hosting.DistributedApplication[0]
      Aspire version: 9.0.0
info: Aspire.Hosting.DistributedApplication[0]
      Distributed application starting.
info: Aspire.Hosting.DistributedApplication[0]
      Application host directory is: ..\AspireApp\AspireApp.AppHost
info: LifecycleLogger[0]
      AfterEndpointsAllocatedAsync
info: Aspire.Hosting.DistributedApplication[0]
      Now listening on: https://localhost:17043
info: Aspire.Hosting.DistributedApplication[0]
      Login to the dashboard at https://localhost:17043/login?t=d80f598bc8a64c7ee97328a1cbd55d72
info: LifecycleLogger[0]
      AfterResourcesCreatedAsync
info: Aspire.Hosting.DistributedApplication[0]
      Distributed application started. Press Ctrl+C to shut down.

A maneira preferida de se conectar ao ciclo de vida do host do aplicativo é usar a API de eventos. Para obter mais informações, consulte Eventos em .NET.NET Aspire.

Contexto de execução

O IDistributedApplicationBuilder expõe um contexto de execução (DistributedApplicationExecutionContext), que fornece informações sobre a execução atual do host do aplicativo. Esse contexto pode ser usado para avaliar se o host do aplicativo está ou não sendo executado no modo "executar" ou como parte de uma operação de publicação. Considere as seguintes propriedades:

  • IsRunMode: Retorna true se a operação atual estiver em execução.
  • IsPublishMode: Retorna true se a operação atual estiver em publicação.

Essas informações podem ser úteis quando você deseja executar condicionalmente o código com base na operação atual. Considere o exemplo a seguir que demonstra o uso da propriedade IsRunMode. Nesse caso, é utilizado um método de extensão para gerar um nome de nó estável para RabbitMQ em execuções de desenvolvimento local.

private static IResourceBuilder<RabbitMQServerResource> RunWithStableNodeName(
    this IResourceBuilder<RabbitMQServerResource> builder)
{
    if (builder.ApplicationBuilder.ExecutionContext.IsRunMode)
    {
        builder.WithEnvironment(context =>
        {
            // Set a stable node name so queue storage is consistent between sessions
            var nodeName = $"{builder.Resource.Name}@localhost";
            context.EnvironmentVariables["RABBITMQ_NODENAME"] = nodeName;
        });
    }

    return builder;
}

O contexto de execução é frequentemente usado para adicionar condicionalmente recursos ou cadeias de conexão que apontam para recursos existentes. Considere o exemplo a seguir que demonstra a adição condicional de Redis ou uma cadeia de conexão com base no contexto de execução:

var builder = DistributedApplication.CreateBuilder(args);

var redis = builder.ExecutionContext.IsRunMode
    ? builder.AddRedis("redis")
    : builder.AddConnectionString("redis");

builder.AddProject<Projects.WebApplication>("api")
       .WithReference(redis);

builder.Build().Run();

No código anterior:

  • Se o host do aplicativo estiver sendo executado no modo "executar", um recurso de contêiner Redis será adicionado.
  • Se o host do aplicativo estiver sendo executado no modo "publicar", uma cadeia de conexão será adicionada.

Essa lógica pode ser facilmente invertida para se conectar a um recurso de Redis existente quando você estiver executando localmente e criar um novo recurso de Redis quando estiver publicando.

Importante

.NET .NET Aspire fornece APIs comuns para controlar a modalidade de construtores de recursos, permitindo que os recursos se comportem de forma diferente com base no modo de execução. As APIs fluentes são prefixadas com RunAs* e PublishAs*. As APIs RunAs* influenciam o comportamento de desenvolvimento local (ou modo de execução), enquanto as APIs PublishAs* influenciam a publicação do recurso. Para obter mais informações sobre como os recursos Azure usam essas APIs, consulte Usar recursos de Azure existentes.

Relações de recursos

As relações de recursos ligam recursos. Os relacionamentos são informativos e não afetam o comportamento de tempo de execução de um aplicativo. Em vez disso, eles são usados ao exibir detalhes sobre recursos no painel. Por exemplo, as relações são visíveis nos detalhes dos recursos do painel , e as relações Parent controlam o aninhamento de recursos na página de recursos.

Os relacionamentos são criados automaticamente por algumas APIs de modelo de aplicativo. Por exemplo:

  • WithReference adiciona uma relação ao recurso de destino com o tipo Reference.
  • WaitFor adiciona uma relação ao recurso de destino com o tipo WaitFor.
  • Adicionar um banco de dados a um contêiner de banco de dados cria uma relação do banco de dados com o contêiner com o tipo Parent.

Os relacionamentos também podem ser explicitamente adicionados ao modelo de aplicativo usando WithRelationship e WithParentRelationship.

var builder = DistributedApplication.CreateBuilder(args);

var catalogDb = builder.AddPostgres("postgres")
                       .WithDataVolume()
                       .AddDatabase("catalogdb");

builder.AddProject<Projects.AspireApp_CatalogDbMigration>("migration")
       .WithReference(catalogDb)
       .WithParentRelationship(catalogDb);

builder.Build().Run();

O exemplo anterior usa WithParentRelationship para configurar catalogdb banco de dados como o pai do projeto migration. A relação Parent é especial porque controla o aninhamento de recursos na página de recursos. Neste exemplo, migration está aninhado em catalogdb.

Observação

Há validação para relacionamentos parentais para evitar que um recurso tenha vários pais ou crie uma referência circular. Essas configurações não podem ser renderizadas na interface do usuário e o modelo do aplicativo gerará um erro.

Ver também