Olá! Na lição anterior, desvendamos a teoria por trás de como o .NET Aspire descobre e injeta configurações para componentes, com base no Padrão Options do ASP.NET Core. Vimos como o AppHost orquestra os recursos e como os pacotes de componentes nos serviços consomem essa configuração de forma transparente.
Hoje, vamos colocar essa teoria em prática. O objetivo desta lição é integrar nosso primeiro e um dos mais comuns componentes em uma aplicação distribuída: um cache. Você aprenderá a integrar o Redis em uma aplicação Aspire usando o componente Aspire.StackExchange.Redis. Este é um passo fundamental para construir aplicações de back-end performáticas e escaláveis.
1. Redis e o Padrão de Cache-Aside
Antes de mergulharmos no código, vamos contextualizar. O Redis é um armazenamento de estrutura de dados em memória, de código aberto, usado como banco de dados, cache, agente de mensagens e muito mais. Sua principal vantagem é a velocidade, pois opera primariamente na RAM.

Em aplicações de back-end, um dos usos mais comuns do Redis é implementar o padrão de cache cache-aside. A lógica é simples:
- Quando um dado é solicitado, a aplicação primeiro verifica se ele existe no cache (Redis).
- Cache Hit: Se o dado está no cache, ele é retornado diretamente, evitando uma consulta custosa ao banco de dados.
- Cache Miss: Se o dado não está no cache, a aplicação o busca na fonte de dados principal (como um banco de dados PostgreSQL), retorna-o ao cliente e, crucialmente, armazena-o no cache para futuras solicitações.
Este padrão reduz drasticamente a carga sobre o banco de dados e diminui a latência das respostas para dados frequentemente acessados. Conceitualmente, nossa arquitetura se parecerá com isto:

2. A Integração em Dois Passos
Lembrando da lição anterior, a integração de um componente Aspire envolve dois projetos:
- O Projeto AppHost: Onde declaramos os recursos da nossa aplicação. Aqui, diremos ao Aspire: "minha aplicação precisa de um contêiner Redis".
- O Projeto de Serviço (API): Onde consumimos os recursos. Aqui, diremos à nossa API: "use aquele contêiner Redis que o AppHost configurou para você como um cache distribuído".
Vamos executar esses dois passos.
3. Passo 1: Configurando o Recurso no AppHost
Primeiro, precisamos informar ao orquestrador do Aspire sobre nossa necessidade de um Redis.
Stack Exchange Redis caching overview - Aspire
A documentação oficial da Microsoft detalha a integração de hospedagem do Redis. Ela é a referência principal para entender as capacidades do componente no AppHost.
Leia as seções "Hosting integration" e "Add Redis resource". Preste atenção em como o método AddRedis é usado para adicionar o recurso. Note também as extensões úteis como WithRedisCommander, que adiciona uma UI para inspecionar o cache, algo muito útil durante o desenvolvimento.
Para colocar isso em prática, siga estes passos no seu projeto:
-
Adicionar o pacote NuGet: No seu projeto
AppHost, instale o pacote de hospedagem do Redis.dotnet add package Aspire.Hosting.Redis -
Modificar o
Program.csdo AppHost: Declare o recurso Redis e estabeleça a referência com o serviço que o utilizará.// Em AppHost/Program.cs var builder = DistributedApplication.CreateBuilder(args); // 1. Adiciona um contêiner Redis como um recurso chamado "cache" var cache = builder.AddRedis("cache"); // Adiciona o projeto da API var apiservice = builder.AddProject<Projects.MyAspireApp_ApiService>("apiservice") // 2. Informa que a API tem uma referência para o cache. // Isso injetará a connection string do Redis no ambiente da API. .WithReference(cache); // ... (outros serviços, como o frontend) builder.Build().Run();
O nome "cache" que passamos para AddRedis é o identificador chave. É através deste nome que o Aspire conectará o recurso no AppHost ao cliente no serviço.
4. Passo 2: Configurando o Cliente no Serviço da API
Agora que o AppHost conhece o Redis, precisamos configurar nossa API para usá-lo. Isso envolve instalar o pacote cliente e registrá-lo no contêiner de injeção de dependência (DI).
Para esta tarefa, usaremos o pacote Aspire.StackExchange.Redis.DistributedCaching. Ele se integra perfeitamente com a abstração IDistributedCache do ASP.NET Core, com a qual você, como desenvolvedor de back-end .NET, provavelmente já está familiarizado.
.NET Aspire Tutorial For Beginners
Este vídeo de Julio Casal demonstra de forma prática todo o processo de integração, começando pela configuração do AppHost e seguindo para a configuração da API. É uma excelente demonstração visual dos passos que estamos seguindo.
Assista ao trecho de 01:05:35 a 01:08:45. Observe como ele: Adiciona a referência ao Redis no AppHost (builder.AddRedis, .WithReference). Instala o pacote cliente na API. Chama builder.AddRedisDistributedCache("Redis") no Program.cs da API, ressaltando a importância de o nome corresponder ao do AppHost.
Resumindo os passos para o seu projeto de API:
- Adicionar o pacote NuGet: No seu projeto de API (
ApiService), instale o pacote cliente para cache distribuído.dotnet add package Aspire.StackExchange.Redis.DistributedCaching - Modificar o
Program.csda API: Chame o método de extensão do Aspire para registrar oIDistributedCache.// Em ApiService/Program.cs var builder = WebApplication.CreateBuilder(args); // Adiciona os padrões de serviço do Aspire (telemetria, health checks, etc.) builder.AddServiceDefaults(); // 1. Registra o cliente de cache distribuído do Redis. // O nome "cache" DEVE corresponder ao nome usado no AppHost. builder.AddRedisDistributedCache("cache"); // ... (restante da configuração de serviços) var app = builder.Build(); // Mapeia os endpoints padrão do Aspire (ex: /health) app.MapDefaultEndpoints(); // ... (restante do pipeline) app.Run();
Pronto! Com essas duas linhas de código, o Aspire cuida de:
- Ler a connection string injetada pelo AppHost.
- Configurar o cliente
StackExchange.Redis. - Registrar uma implementação de
IDistributedCacheno contêiner de DI. - Adicionar automaticamente health checks e telemetria (tracing e métricas) para cada chamada ao Redis.
Teste seu entendimento!
Você configurou seu AppHost com builder.AddRedis("my-cache") e seu serviço de API com builder.AddRedisDistributedCache("default-cache"). Ao executar o aplicativo, sua API lança uma exceção informando que não consegue se conectar ao Redis. Qual é a causa mais provável desse erro?
Show answer
A causa mais provável é a incompatibilidade entre os nomes dos recursos. O nome é a "chave" que liga a definição do recurso no AppHost ("my-cache") à configuração do cliente no serviço ("default-cache"). Para que o Aspire injete a connection string correta, esses nomes devem ser idênticos.
5. Implementando o Padrão Cache-Aside
Com a configuração completa, o uso do cache no código da sua aplicação é exatamente como você faria com IDistributedCache em qualquer aplicação ASP.NET Core.
.NET Aspire Tutorial For Beginners
Continuando com o vídeo anterior, esta seção mostra como modificar um endpoint de API para implementar o padrão cache-aside. É uma aplicação prática e direta do que acabamos de configurar.
Assista ao trecho de 01:08:45 a 01:12:32. Preste atenção à lógica de programação: Injetar IDistributedCache no endpoint. Tentar obter o item do cache primeiro (cache.GetStringAsync). Se for um cache miss (nulo), buscar no banco de dados. Armazenar o resultado no cache (cache.SetStringAsync) com um tempo de expiração antes de retornar.
Aqui está um exemplo conciso de como isso ficaria em um endpoint de API Mínima:
// Em ApiService, onde os endpoints são mapeados
app.MapGet("/products/{id}", async (int id, IDistributedCache cache, ProductDbContext dbContext) =>
{
// 1. Define uma chave única para o item no cache.
string cacheKey = $"product-{id}";
// 2. Tenta obter o produto do cache.
string? cachedProductJson = await cache.GetStringAsync(cacheKey);
if (cachedProductJson is not null)
{
// Cache Hit: Deserializa e retorna o produto do cache.
var cachedProduct = JsonSerializer.Deserialize<Product>(cachedProductJson);
return Results.Ok(cachedProduct);
}
// 3. Cache Miss: Busca o produto no banco de dados.
var productFromDb = await dbContext.Products.FindAsync(id);
if (productFromDb is null)
{
return Results.NotFound();
}
// 4. Armazena o produto no cache para a próxima vez.
var options = new DistributedCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromMinutes(5));
string productToCacheJson = JsonSerializer.Serialize(productFromDb);
await cache.SetStringAsync(cacheKey, productToCacheJson, options);
return Results.Ok(productFromDb);
});
6. Verificação e Observabilidade no Dashboard
A verdadeira "mágica" do Aspire se revela quando executamos a aplicação e olhamos para o Dashboard. É aqui que vemos os benefícios da telemetria integrada.
.NET Aspire Tutorial For Beginners
Esta seção final do vídeo é crucial. Ela mostra como usar o Aspire Dashboard para verificar se a integração com o Redis está funcionando e, mais importante, para observar o impacto no desempenho da aplicação através de logs e traces distribuídos.
Assista ao trecho de 01:12:32 a 01:19:38. Foque em observar: O contêiner Redis aparecendo na lista de Recursos. Os logs estruturados mostrando as mensagens de "cache miss". A diferença fundamental nos traces distribuídos entre a primeira chamada (cache miss), que inclui a consulta ao banco de dados, e a segunda chamada (cache hit), que é muito mais rápida e vai apenas até o Redis.
Ao executar seu AppHost e fazer requisições ao seu endpoint:
- Primeira Requisição (Cache Miss): Vá para a aba Traces no Aspire Dashboard. Você verá um trace distribuído que mostra a requisição chegando na sua API, fazendo uma chamada ao Redis (que falha em encontrar o item), depois fazendo uma chamada ao seu banco de dados e, finalmente, outra chamada ao Redis para salvar o item.
- Segunda Requisição (Cache Hit): Faça a mesma requisição novamente. Agora, o trace será muito mais simples e rápido. Ele mostrará a requisição chegando à API e fazendo uma única chamada ao Redis para obter o dado. O banco de dados não será contatado.
Essa visualização lado a lado de um cache hit vs. um cache miss é uma ferramenta de diagnóstico e aprendizado incrivelmente poderosa, fornecida "de graça" pelo Aspire.
Conclusão
Nesta lição, demos nosso primeiro passo prático na construção de uma aplicação cloud-native com Aspire, aplicando a teoria da lição anterior.
Principais Pontos:
- A integração de um componente como o Redis é um processo de dois passos: declarar o recurso no AppHost (
builder.AddRedis) e configurar o cliente no serviço (builder.AddRedisDistributedCache). - O nome do recurso é a chave que conecta a configuração do AppHost ao cliente no serviço.
- Usando o pacote
Aspire.StackExchange.Redis.DistributedCaching, podemos injetar a abstração padrãoIDistributedCachepara implementar padrões de cache como o cache-aside. - O Aspire Dashboard é essencial para verificar a integração e observar o comportamento da aplicação através de logs estruturados e, mais importante, traces distribuídos, que visualizam o fluxo de uma requisição através dos serviços.
Agora que você dominou a integração de um componente de cache, estamos prontos para abordar a persistência de dados. Na próxima lição, aplicaremos exatamente os mesmos princípios para integrar um banco de dados PostgreSQL usando o componente Aspire.Npgsql.