Personalizar cadeias de conexão usando manifestos do .NET Aspire

Concluído

Ferramentas de implantação como o Visual Studio ou a CLI do Desenvolvedor do Azure criam arquivos de manifesto que descrevem o conteúdo de uma solução .NET Aspire . Se quiser personalizar sua implantação, você pode fazer alterações no arquivo de manifesto diretamente.

Em seu revendedor de equipamentos externos, você decidiu usar uma instância existente do Cache do Azure para Redis para hospedar o cache de saída para seu microsserviço de aplicativo Web. Você deseja garantir que o serviço de aplicativo Web se conecte à instância correta do Cache do Azure para Redis.

Nesta unidade, você aprenderá como alterar cadeias de conexão para serviços de backup no arquivo de manifesto do .NET Aspire .

Gerar um arquivo de manifesto usando a CLI do .NET

Durante o desenvolvimento local e a depuração, o .NET Aspire não cria um ficheiro de manifesto. Quando se trata de implantação, o .NET deve descrever o conteúdo da solução .NET Aspire , incluindo seus microsserviços, serviços de suporte e configuração. O ficheiro de manifesto serve este propósito. Ele descreve a solução no formato JSON.

Para criar o arquivo de manifesto, o Visual Studio e a CLI do Desenvolvedor do Azure executam um comando da CLI run do .NET com um destino específico. Você pode executar manualmente o mesmo comando para criar seu próprio arquivo de manifesto da seguinte forma:

dotnet run --project eShop.AppHost\eShop.AppHost.csproj `
    --publisher manifest `
    --output-path ../aspire-manifest.json

Nota

Certifique-se de especificar o projeto de host do aplicativo com a --project opção.

O comando produz uma saída semelhante a este texto:

Building...
info: Aspire.Hosting.DistributedApplication[0]
      Aspire version: 8.0.1+a6e341ebbf956bbcec0dda304109815fcbae70c9
info: Aspire.Hosting.Publishing.ManifestPublisher[0]
      Published manifest to: C:\repos\eShop\aspire-manifest.json

Você também pode usar um perfil de inicialização para executar o dotnet comando. Um perfil de inicialização é um grupo de configurações que define um projeto .NET quando ele é executado. Por exemplo, o modelo .NET Aspire Starter cria estes perfis de inicialização:

"profiles": {
  "https": {
    "commandName": "Project",
    "dotnetRunMessages": true,
    "launchBrowser": true,
    "applicationUrl": "https://localhost:17170;http://localhost:15281",
    "environmentVariables": {
      "ASPNETCORE_ENVIRONMENT": "Development",
      "DOTNET_ENVIRONMENT": "Development",
      "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21147",
      "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22239"
    }
  },
  "http": {
    "commandName": "Project",
    "dotnetRunMessages": true,
    "launchBrowser": true,
    "applicationUrl": "http://localhost:15281",
    "environmentVariables": {
      "ASPNETCORE_ENVIRONMENT": "Development",
      "DOTNET_ENVIRONMENT": "Development",
      "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19197",
      "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20233"
    }
  }
}

Adicione um perfil de inicialização para criar um arquivo de manifesto com código JSON semelhante a este texto:

"profiles": {
  "generate-manifest": {
    "commandName": "Project",
    "launchBrowser": false,
    "dotnetRunMessages": true,
    "commandLineArgs": "--publisher manifest --output-path aspire-manifest.json"
  }
}

No Visual Studio, você pode escolher o perfil generate-manifest quando iniciar a depuração. Na linha de comando, use a --launch-profile opção:

dotnet run --launch-profile generate-manifest

Formato do ficheiro de manifesto

O manifesto é um arquivo JSON com um único elemento de nível superior chamado resources. Dentro desse objeto, você encontra um objeto para cada microsserviço e serviço de suporte. Para cada um desses objetos, as configurações incluem cadeias de conexão, variáveis de ambiente e nomes de imagem de contêiner.

Aqui está um exemplo de manifesto para o modelo .NET Aspire Starter sem modificações. A solução usa um cache Redis:

{
  "resources": {
    "cache": {
      "type": "container.v0",
      "connectionString": "{cache.bindings.tcp.host}:{cache.bindings.tcp.port}",
      "image": "docker.io/library/redis:7.2",
      "bindings": {
        "tcp": {
          "scheme": "tcp",
          "protocol": "tcp",
          "transport": "tcp",
          "targetPort": 6379
        }
      }
    },
    "apiservice": {
      "type": "project.v0",
      "path": "AspireStarter.ApiService/AspireStarter.ApiService.csproj",
      "env": {
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY": "in_memory",
        "ASPNETCORE_FORWARDEDHEADERS_ENABLED": "true"
      },
      "bindings": {
        "http": {
          "scheme": "http",
          "protocol": "tcp",
          "transport": "http"
        },
        "https": {
          "scheme": "https",
          "protocol": "tcp",
          "transport": "http"
        }
      }
    },
    "webfrontend": {
      "type": "project.v0",
      "path": "AspireStarter.Web/AspireStarter.Web.csproj",
      "env": {
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY": "in_memory",
        "ASPNETCORE_FORWARDEDHEADERS_ENABLED": "true",
        "ConnectionStrings__cache": "{cache.connectionString}",
        "services__apiservice__http__0": "{apiservice.bindings.http.url}",
        "services__apiservice__https__0": "{apiservice.bindings.https.url}"
      },
      "bindings": {
        "http": {
          "scheme": "http",
          "protocol": "tcp",
          "transport": "http",
          "external": true
        },
        "https": {
          "scheme": "https",
          "protocol": "tcp",
          "transport": "http",
          "external": true
        }
      }
    }
  }
}

Cadeias de conexão e referências de vinculação

No exemplo do manifesto, há três recursos:

  • webfrontend: Este recurso é o microsserviço que apresenta uma interface web aos clientes.
  • apiservice: Este recurso é a API REST que as webfrontend chamadas. No modelo, esta chamada é para obter dados meteorológicos.
  • cache: Este recurso é o cache Redis, usado para otimizar o desempenho do webfrontend microsserviço.

Observe que cada um dos três recursos inclui uma bindings seção que especifica os protocolos que você pode usar para se conectar a esse recurso.

No arquivo Program.cs do host do aplicativo, o webfrontend projeto depende do cache e do apiservice:

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

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

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

No arquivo de manifesto, essas dependências são expressas como variáveis de ambiente:

"env": {
  "ConnectionStrings__cache": "{cache.connectionString}",
  "services__apiservice__http__0": "{apiservice.bindings.http.url}",
  "services__apiservice__https__0": "{apiservice.bindings.https.url}"
}

Diagrama mostrando como as dependências em um projeto .NET Aspire geram referências em um arquivo de manifesto.

As dependências usam cadeias de caracteres de espaço reservado que fazem referência à estrutura do arquivo de manifesto. Por exemplo, a terceira dependência faz referência à vinculação HTTPS do serviço de API:

Diagrama mostrando como os espaços reservados são construídos em um arquivo de manifesto do .NET Aspire .

Mais informações