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 monitore com eficiência seus aplicativos distribuídos. Esses recursos são alimentados por um modelo de aplicativo, que define os recursos em sua .NET.NET Aspire solução e suas interconexões.

O modelo de aplicativo é mais do que apenas uma lista de recursos: ele representa a topologia completa do seu aplicativo. Isso inclui as relações entre recursos, suas dependências e suas configurações. Os recursos podem incluir projetos, executáveis, contêineres, serviços externos e recursos de nuvem dos quais seu aplicativo depende.

No seu.NET.NET Aspire projeto de host de aplicativo, seu Program arquivo define seu modelo de aplicativo:

var builder = DistributedApplication.CreateBuilder(args);

// Add resources to the app model

builder.Build().Run();

Ao chamar DistributedApplication.CreateBuilder, obtém-se uma instância de IDistributedApplicationBuilder, que é utilizada para configurar o modelo da sua aplicação. Esse construtor fornece métodos para adicionar recursos, definir dependências e configurar a estrutura geral do seu aplicativo. Depois de adicionar recursos, ligue Build para criar o modelo de aplicativo. Os modelos incluem código que encadeia uma chamada para Build(), que primeiro retorna uma instância DistributedApplication e, em seguida, chama 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 .NET projeto executável que faz referência ao 📦Aspire. Pacote NuGet Hosting.AppHost e usa o .NET.NET Aspire SDK:

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

    <Sdk Name="Aspire.AppHost.Sdk" Version="9.1.0" />
    
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net9.0</TargetFramework>
        <!-- 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.

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 Redis cache. 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".

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.

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 no modo "executar", um Redis recurso de contêiner será adicionado.
  • Se o host do aplicativo estiver 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.

Ver também