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!

💡
Podemos te ajudar com uma revisão 100% gratuita do seu ambiente cloud.
Share this post