Olá! Na lição anterior, você integrou um cache Redis à sua aplicação Aspire, aprendendo o padrão fundamental de dois passos: declarar um recurso no AppHost e consumi-lo em um serviço. Vimos como o nome do recurso é a chave que conecta os dois e como o Aspire Dashboard nos dá visibilidade sobre o comportamento da aplicação.
Hoje, vamos dar o próximo passo lógico: da gestão de dados voláteis (cache) para a persistência de dados. O objetivo desta lição é configurar um banco de dados PostgreSQL usando o componente Aspire.Npgsql. Você verá que o padrão de integração é exatamente o mesmo que aprendeu com o Redis, o que demonstra a consistência e a força do modelo de componentes do Aspire.
Vamos substituir um banco de dados de desenvolvimento, como o SQLite, por uma solução robusta e pronta para produção como o PostgreSQL, uma etapa crucial na criação de aplicações distribuídas.
O Padrão de Integração do Aspire: Revisitado
Lembre-se do padrão que usamos para o Redis:
- AppHost: Usamos um pacote
Aspire.Hosting.*para declarar o contêiner Redis. - Serviço (API): Usamos um pacote
Aspire.*para configurar o cliente que se conecta ao Redis. - Conexão: O nome do recurso e a chamada
.WithReference()conectam os dois, injetando aconnection stringautomaticamente.
Para o PostgreSQL, a abordagem é idêntica. Usaremos os pacotes:
Aspire.Hosting.PostgreSQLno projeto AppHost.Aspire.Npgsql.EntityFrameworkCore.PostgreSQLno seu projeto de serviço (API) que usa Entity Framework Core.
A arquitetura que estamos construindo pode ser visualizada da seguinte forma:

Este diagrama mostra a relação que vamos estabelecer: o AppHost do Aspire orquestra uma Web API que, por sua vez, depende de um banco de dados PostgreSQL para persistência. O Aspire gerencia a conexão entre eles.
Passo 1: Configurar o Recurso PostgreSQL no AppHost
Assim como no Redis, o primeiro passo é declarar o nosso banco de dados como um recurso no Program.cs do AppHost. No entanto, com bancos de dados, temos um conceito novo e importante: recursos pai e filho. O servidor PostgreSQL é o recurso "pai", e o banco de dados específico dentro desse servidor é o recurso "filho".
Aspire PostgreSQL Entity Framework Core integration
A documentação oficial do Aspire é a melhor fonte para entender todas as opções disponíveis. Ela detalha como adicionar o servidor PostgreSQL, criar bancos de dados e configurar aspectos importantes como persistência.
Leia as seções "Hosting integration", "Add PostgreSQL server resource", "Add PostgreSQL pgAdmin resource" e "Add PostgreSQL server resource with data volume". Foco em como os métodos AddPostgres, AddDatabase, WithPgAdmin e WithDataVolume são encadeados para construir a configuração do recurso.
Para começar, adicione o pacote NuGet de hospedagem ao seu projeto AppHost:
dotnet add package Aspire.Hosting.PostgreSQL
Agora, vamos modificar o Program.cs do AppHost.
.NET Aspire Tutorial For Beginners
Este vídeo de Julio Casal é um guia prático excelente que demonstra a substituição de um banco de dados SQLite por PostgreSQL em uma aplicação Aspire. Ele cobre todos os detalhes que estamos discutindo.
Assista aos trechos de 15:36 a 27:45. Observe atentamente como ele: Adiciona o recurso do servidor PostgreSQL com builder.AddPostgres(). Adiciona um banco de dados específico como um recurso filho com .AddDatabase(). Configura a persistência de dados com .WithDataVolume(), um passo essencial para bancos de dados. Adiciona uma interface de gerenciamento com .WithPgAdmin() para facilitar o desenvolvimento.
Com base nos recursos, seu código no AppHost ficará parecido com isto:
// Em AppHost/Program.cs
var builder = DistributedApplication.CreateBuilder(args);
// 1. Adiciona o servidor PostgreSQL como um recurso pai, nomeado 'postgres'.
var postgresServer = builder.AddPostgres("postgres");
// 2. Adiciona um banco de dados específico, nomeado 'gamestoredb', como filho do servidor.
// Este nome ('gamestoredb') será a chave da sua connection string!
var database = postgresServer.AddDatabase("gamestoredb");
// 3. (Opcional, mas recomendado) Adiciona uma UI para gerenciar o banco de dados.
postgresServer.WithPgAdmin();
// 4. (Crucial) Persiste os dados do PostgreSQL usando um volume Docker.
postgresServer.WithDataVolume();
// Adiciona o projeto da API, que usará este banco de dados.
var apiService = builder.AddProject<Projects.MyAspireApp_ApiService>("apiservice")
// A referência será adicionada no Passo 3.
.WithReference(database);
// ...
builder.Build().Run();
Pontos-chave aqui:
AddPostgres("postgres"): Inicia um contêiner Docker com o servidor PostgreSQL. O nome"postgres"é um identificador interno para este recurso no Aspire.AddDatabase("gamestoredb"): Cria um banco de dados chamadogamestoredbdentro do servidor PostgreSQL assim que o servidor estiver pronto. O nome que você fornece aqui é fundamental, pois ele se tornará o nome da suaconnection string.WithDataVolume(): Diferente do Redis (cache), onde a perda de dados ao reiniciar o contêiner pode ser aceitável, para um banco de dados, a persistência é obrigatória. Este método cria um volume Docker que sobrevive ao ciclo de vida do contêiner, garantindo que seus dados não sejam perdidos.WithPgAdmin(): Similar aoWithRedisCommanderda lição anterior, este método adiciona outro contêiner com uma interface web (pgAdmin) para você inspecionar e gerenciar seu banco de dados facilmente durante o desenvolvimento.
Passo 2: Configurar o Cliente EF Core no Serviço da API
Com o AppHost configurado, o próximo passo é instruir sua API a usar este banco de dados. Isso envolve substituir a configuração do DbContext do Entity Framework Core para usar o provedor Npgsql do Aspire.
Primeiro, adicione o pacote cliente ao seu projeto de API:
dotnet add package Aspire.Npgsql.EntityFrameworkCore.PostgreSQL
Agora, modifique o Program.cs da sua API para usar o novo método de extensão fornecido pelo Aspire.
.NET Aspire Tutorial For Beginners
Continuando no mesmo vídeo, esta seção mostra como modificar o código da API para se conectar ao novo banco de dados PostgreSQL gerenciado pelo Aspire.
Assista ao trecho de 30:48 a 34:24. O ponto principal é a substituição do método de registro do DbContext. Observe como ele remove a configuração antiga (para SQLite) e a substitui por uma única chamada a builder.AddNpgsqlDbContext().
A mudança no seu código será mais ou menos assim:
Antes (Exemplo com SQLite):
// Em ApiService/Program.cs
// ...
var connectionString = builder.Configuration.GetConnectionString("Games");
builder.Services.AddSqlite<GameStoreContext>(connectionString);
// ...
Depois (com Aspire e Npgsql):
// Em ApiService/Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
// 1. Remove qualquer configuração de DbContext antiga.
// 2. Adiciona o DbContext usando o método de extensão do Aspire.
// O nome "gamestoredb" DEVE corresponder ao nome usado em AddDatabase() no AppHost.
builder.AddNpgsqlDbContext<GameStoreContext>("gamestoredb");
// ... (configuração de outros serviços)
var app = builder.Build();
// ...
app.Run();
É só isso! A chamada AddNpgsqlDbContext cuida de tudo:
- Espera que o Aspire injete uma
connection stringchamadagamestoredb. - Configura o
DbContextpara usar o Npgsql com essaconnection string. - Adiciona automaticamente health checks para verificar a saúde do banco de dados.
- Configura a telemetria (logs, traces, métricas) para cada consulta ao banco de dados via OpenTelemetry.
Agora podemos remover a connection string do nosso arquivo appsettings.json, pois o Aspire irá gerenciá-la dinamicamente.
Passo 3: Conectar Tudo com WithReference
O último passo é fazer a conexão explícita no AppHost, exatamente como fizemos com o Redis.
// Em AppHost/Program.cs
// ...
var database = postgresServer.AddDatabase("gamestoredb");
var apiService = builder.AddProject<Projects.MyAspireApp_ApiService>("apiservice")
// Esta linha informa ao Aspire que 'apiService' depende do 'database'.
// Aspire injetará a connection string do 'database' no 'apiService'.
.WithReference(database);
// ...
O método WithReference(database) é o que aciona a "mágica": ele informa ao Aspire que o apiService precisa se conectar ao recurso database. Em tempo de execução, o Aspire irá gerar a connection string completa para o contêiner PostgreSQL e a injetará como uma variável de ambiente no processo do apiService, com o nome ConnectionStrings__gamestoredb. O método AddNpgsqlDbContext("gamestoredb") na API sabe como ler essa variável de ambiente.
Teste seu entendimento!
Você configurou seu AppHost com postgresServer.AddDatabase("production_db"), mas na sua API você chamou builder.AddNpgsqlDbContext<MyContext>("development_db"). O que acontecerá quando você iniciar a aplicação?
Show answer
A sua API irá falhar ao iniciar, provavelmente com uma exceção indicando que a connection string chamada development_db não pôde ser encontrada. O Aspire injetou a connection string com o nome production_db (correspondendo à chamada AddDatabase), mas o cliente EF Core na API está procurando por uma com o nome development_db. Os nomes devem ser idênticos para que a conexão funcione.
Verificação e Observabilidade
Agora, a melhor parte: ver tudo funcionando. Execute seu projeto AppHost e abra o Aspire Dashboard.
- Recursos no Dashboard: Você verá os novos recursos em execução: o contêiner
postgres, seu filhogamestoredbe o contêinerpostgres-pgadmin.

*Um exemplo do Aspire Dashboard mostrando os recursos PostgreSQL, Redis e os projetos da aplicação, todos orquestrados pelo Aspire.*
2. Verificar a Connection String: Clique no seu apiService no dashboard, vá para a aba de Environment variables e você encontrará a variável ConnectionStrings__gamestoredb com um valor totalmente preenchido.
- Explorar com pgAdmin: No dashboard, o recurso
postgres-pgadminterá um link de endpoint. Clique nele para abrir a interface do pgAdmin. Você verá que ele já está conectado ao seu servidor de banco de dados. Expanda os servidores e você encontrará seugamestoredb. Se você usa EF Core Migrations, poderá ver que suas tabelas já foram criadas.
.NET Aspire Tutorial For Beginners
Para fechar o ciclo, vamos ver a verificação na prática. Este trecho final do vídeo mostra como usar o dashboard e o pgAdmin para confirmar que tudo está conectado e funcionando como esperado.
Assista ao trecho de 35:59 a 41:27. Preste atenção em como ele: Usa o dashboard para inspecionar as variáveis de ambiente injetadas na API. Abre o pgAdmin a partir do link do dashboard para verificar se as tabelas foram criadas pelas migrações do EF Core. Testa os endpoints da API para confirmar que os dados estão sendo lidos e escritos no banco de dados PostgreSQL.
Conclusão
Parabéns! Você substituiu com sucesso um banco de dados de desenvolvimento por PostgreSQL, usando o mesmo padrão consistente e poderoso do .NET Aspire que você aprendeu na lição anterior.
Principais Pontos:
- A integração de componentes no Aspire segue um padrão consistente, seja para um cache como o Redis ou um banco de dados como o PostgreSQL.
- O Aspire modela recursos de banco de dados como uma relação pai-filho (
AddPostgreseAddDatabase). - O nome fornecido a
AddDatabase()se torna a chave daconnection stringque conecta o AppHost e o serviço. - A persistência de dados é garantida com
WithDataVolume(), um conceito crucial ao trabalhar com bancos de dados em contêineres. - Ferramentas como
WithPgAdmin()e o Aspire Dashboard fornecem uma experiência de desenvolvimento local fantástica para verificação e observabilidade.
Com o cache e a persistência de dados dominados, estamos prontos para explorar outro pilar das arquiteturas distribuídas: a comunicação assíncrona.
Próxima lição: Na próxima aula, você aprenderá a integrar uma fila de mensagens RabbitMQ em uma aplicação Aspire, permitindo que seus serviços se comuniquem de forma desacoplada e resiliente.