O .NET Aspire é uma plataforma lançada juntamente com o .NET 8, composto de aplicativos distribuídos, otimizados para a nuvem, observáveis e prontos para produção. Ele é disponibilizado por meio de um conjunto de pacotes NuGet que abordam preocupações específicas relacionadas à nuvem. Aplicativos nativos da nuvem são geralmente compostos por pequenos microsserviços interconectados, em vez de um único código monolítico, e costumam consumir diversos serviços, como bancos de dados, mensageria e armazenamento em cache.
Para esse post, vamos precisar que você possua os seguintes itens em sua máquina local:
Além disso, vamos precisar do .NET Aspire workload que pode ser instalado diretamente via CLI:
dotnet workload install aspire
Case você esteja utilizando o Visual Studio, recomendo a leitura dessa parte!
Para construir o template padrão do .NET Aspire, vamos executar o seguinte comando:
dotnet new aspire-starter
Temos a estrutura da solução:
- ServicesDefault: projeto responsável em configurar as dependências que serão usadas na solução (Cache, banco de dados, etc ...) além das configurações gerais;
- AppHost: projeto responsável pela orquestração dos outros serviços. Esse projeto que deve ser executado (via VS Code, Visual Studio ou CLI) para levantar toda a solução;
- ApiService: projeto de backend. É uma aplicação do tipo minimal API;
- Web: Projeto de frontend. É uma aplicação blazor.
Antes de executarmos o template, vamos fazer uma pequena modificação no Program.cs do projeto apiService. Iremos fazer a injeção da interface ILogger<Program> e fazer um registro de log logo no começo da execução do endpoint /weatherforecast.
app.MapGet("/weatherforecast", ([FromServices] ILogger<Program> logger) =>
{
logger.LogInformation("Weatherforecast endpoint executed!");
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
});
Além disso, o VS Code irá pedir para criar os arquivos necessários para execução da solução. Com os arquivos prontos, vamos apenas trocar o valor de internalConsole para integratedTerminal, como mostrado abaixo:
Com as modificações prontas, vamos executar a solução via VS Code (Estamos executando o projeto .AppHost).
Ctrl + F5
Podemos verificar que a solução está rodando com sucesso. Vamos acessar o dashboard!
Como mostrado acima, podemos ver que temos dois projetos sendo executados: o frontend (webfrontend) e o backend (apiservice). Além disso, podemos ver quais são as portas do localhost que estão reservadas para essas aplicações.
Vamos acessar o frontend no caminho /weatherforecast.
Essa página faz a busca de dados no backend e renderiza os dados no browser. Voltando ao dashboard, podemos ver foram gerados Logs, Structured logs e Traces dessa requisição!
Vamos simular uma exception nessa chamada e verificar como que esse erro é mostrado pelo dashboard. No endpoint /weatherforecast, vamos remover o log e lançar uma exception genérica.
app.MapGet("/weatherforecast", ([FromServices] ILogger<Program> logger) =>
{
throw new Exception("Error!");
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
});
Executando novamente a solução e refazendo a chamada, podemos ver que o frontend realizou 4 chamada HTTP, e para cada chamada, f0i lançada uma exception. Isso aconteceu porque existe uma integração do IHttpClientFactory do frontend com o Polly!
Vale um estudo mais profundo sobre o Polly!
No .NET Aspire, existe o conceito de components. Esses componentes são pacotes NuGet especializados em simplificar a integração de plataformas e serviços populares as soluções criadas com o Aspire. Esses serviços podem ser: bancos de dados, cache, storage e outros!
Por exemplo, para adicionarmos o component do Azure cosmos DB a nossa solução, basta seguirmos os seguintes passos:
- Adicionar o componente via pacote NuGet:
dotnet add package Aspire.Microsoft.Azure.Cosmos --prerelease
- Fazer o registro do componente:
builder.AddAzureCosmosDB("cosmosConnectionName");
- Configuração da ConnectionString (via appsettings.json):
{
"ConnectionStrings": {
"cosmosConnectionName": "<your-connection-string>"
}
}
Dessa forma, teremos o CosmosClient pronto para ser injetado via DI como singleton em nossa solução!
Ainda falaremos muito sobre o .NET Aspire! Recomendo que você veja a documentação oficial e aprofunde mais nos conceitos que essa ferramenta tem a oferecer!
Você já pode baixar o projeto por esse link, e não esquece de me seguir no LinkedIn!
Até a próxima, abraços!