.NET MAUI com .NET Aspire: Guia Completo para Integrar Apps Móveis com Serviços Backend

Aprenda a integrar o .NET MAUI com o .NET Aspire para simplificar a conexão entre apps móveis e serviços backend. Guia prático com Dev Tunnels, descoberta de serviços e código funcional.

Por Que a Integração do .NET MAUI com o .NET Aspire Muda Tudo

Se você já desenvolveu aplicações móveis com .NET MAUI que precisam se conectar a serviços web locais durante o desenvolvimento, sabe exatamente a dor de cabeça que isso pode ser. URLs diferentes para cada plataforma, aquele famoso 10.0.2.2 no Android, configurações de segurança de rede, certificados SSL... É uma lista interminável de configurações manuais que consomem tempo e — convenhamos — geram uma frustração desnecessária.

Pois é. Com o .NET 10 e o .NET Aspire 13, boa parte disso simplesmente some. A integração oficial entre .NET MAUI e .NET Aspire automatiza toda essa configuração de rede, oferece descoberta automática de serviços e traz observabilidade completa pro seu fluxo de desenvolvimento. Neste guia, a gente vai explorar tudo desde os conceitos fundamentais até a implementação prática com código funcional.

O Que é o .NET Aspire e Por Que Ele Importa para Mobile

O .NET Aspire é uma stack opinativa e pronta para a nuvem, criada pela Microsoft para simplificar a construção de aplicações distribuídas. Ele fornece:

  • Orquestração: Gestão simplificada de múltiplos serviços e dependências — com um único ponto de controlo para toda a sua infraestrutura de desenvolvimento.
  • Componentes pré-construídos: Integrações prontas para serviços comuns como bancos de dados, caches e filas de mensagens.
  • Dashboard de monitoramento: Um painel visual para monitorar logs, traces e métricas de todos os serviços em tempo real.
  • Descoberta de serviços: Configuração automática para comunicação entre serviços, sem URLs hardcoded.

Para o desenvolvimento mobile com .NET MAUI, o Aspire resolve um problema bem concreto: eliminar a complexidade de conectar a sua app a APIs e serviços backend durante o ciclo de desenvolvimento. Em vez de configurar manualmente endereços de rede para cada plataforma (e rezar pra funcionar), o Aspire cuida de tudo automaticamente.

Pré-requisitos e Versões Necessárias

Antes de começar, certifique-se de ter instalado:

  • .NET 10 SDK ou superior
  • .NET Aspire 13 ou superior (inclui o pacote Aspire.Hosting.Maui em preview)
  • Uma aplicação .NET MAUI direcionada ao .NET 10 ou posterior
  • Um ou mais serviços web (Web API, gRPC, etc.)
  • Visual Studio 2026 com o workload .NET MAUI instalado, ou VS Code com as extensões .NET e C# Dev Kit

Nota importante: esta funcionalidade está atualmente em preview. A integração com o Visual Studio 2026 ainda não está completamente disponível, mas já dá pra trabalhar pela linha de comandos e pelo VS Code sem maiores problemas.

Arquitetura da Integração: Como Funciona por Dentro

A integração .NET MAUI + Aspire funciona com base em três componentes principais que trabalham juntos:

1. Projeto App Host (Orquestrador)

O App Host é o cérebro da operação. Ele regista todos os serviços da sua solução — incluindo a app MAUI e as APIs backend — e configura a comunicação entre eles. Quando você inicia o App Host, ele arranca automaticamente todos os serviços e disponibiliza o dashboard de monitoramento.

2. Projeto MAUI Service Defaults

Este projeto contém a configuração partilhada que a sua app MAUI vai usar para se conectar aos serviços. Inclui configuração de descoberta de serviços, padrões de resiliência, telemetria com OpenTelemetry e configuração de rede específica por plataforma. É pequenininho, mas faz muita coisa.

3. Dev Tunnels (para iOS e Android)

No Windows e Mac Catalyst, a conexão com serviços locais funciona diretamente via localhost. Mas no iOS e Android — emuladores e dispositivos físicos — o Aspire utiliza Dev Tunnels: túneis seguros que expõem os seus serviços locais para dispositivos móveis, sem necessidade de configuração manual de rede.

Configuração Passo a Passo

Passo 1: Criar o Projeto MAUI Service Defaults

O primeiro passo é criar o projeto de configurações padrão que o MAUI vai utilizar. Abra o terminal na raiz da sua solução:

dotnet new maui-aspire-servicedefaults -n MinhaApp.MauiServiceDefaults
dotnet sln add MinhaApp.MauiServiceDefaults/MinhaApp.MauiServiceDefaults.csproj

Em seguida, adicione a referência ao projeto MAUI principal:

dotnet add MinhaApp/MinhaApp.csproj reference MinhaApp.MauiServiceDefaults/MinhaApp.MauiServiceDefaults.csproj

Este projeto inclui automaticamente a configuração de descoberta de serviços, padrões de resiliência com Polly e integração com OpenTelemetry. Pouca coisa pra configurar, bastante coisa que ele entrega.

Passo 2: Criar o Projeto App Host

O App Host é o orquestrador de toda a solução:

dotnet new aspire-apphost -n MinhaApp.AppHost
dotnet sln add MinhaApp.AppHost/MinhaApp.AppHost.csproj

Adicione as referências necessárias ao App Host:

dotnet add MinhaApp.AppHost/MinhaApp.AppHost.csproj reference MinhaApp/MinhaApp.csproj
dotnet add MinhaApp.AppHost/MinhaApp.AppHost.csproj reference MinhaApp.WebApi/MinhaApp.WebApi.csproj

E instale o pacote NuGet de hosting para MAUI:

dotnet add package Aspire.Hosting.Maui --version 13.0.0-preview.1.25560.3 --project MinhaApp.AppHost/MinhaApp.AppHost.csproj

Passo 3: Configurar o App Host (Program.cs)

Aqui é onde a magia acontece de verdade. No ficheiro Program.cs do App Host, registamos todos os serviços e dispositivos alvo:

var builder = DistributedApplication.CreateBuilder(args);

// Registar o serviço Web API
var weatherApi = builder.AddProject("webapi",
    @"../MinhaApp.WebApi/MinhaApp.WebApi.csproj");

// Criar um Dev Tunnel público para iOS e Android
var publicDevTunnel = builder.AddDevTunnel("devtunnel-publico")
    .WithAnonymousAccess()
    .WithReference(weatherApi.GetEndpoint("https"));

// Registar a aplicação MAUI
var mauiapp = builder.AddMauiProject("mauiapp",
    @"../MinhaApp/MinhaApp.csproj");

// Configurar dispositivos Windows e Mac (usam localhost diretamente)
mauiapp.AddWindowsDevice()
    .WithReference(weatherApi);

mauiapp.AddMacCatalystDevice()
    .WithReference(weatherApi);

// Configurar simulador iOS com Dev Tunnel
mauiapp.AddiOSSimulator()
    .WithOtlpDevTunnel()
    .WithReference(weatherApi, publicDevTunnel);

// Configurar emulador Android com Dev Tunnel
mauiapp.AddAndroidEmulator()
    .WithOtlpDevTunnel()
    .WithReference(weatherApi, publicDevTunnel);

builder.Build().Run();

Repare em alguns pontos importantes neste código:

  • O WithAnonymousAccess() é necessário para que os emuladores/simuladores possam acessar o túnel sem autenticação.
  • O WithOtlpDevTunnel() cria um túnel específico para tráfego OpenTelemetry, essencial para ver métricas e traces da app móvel no dashboard do Aspire.
  • Você pode adicionar múltiplos dispositivos para a mesma plataforma — por exemplo, dois emuladores Android com configurações diferentes.

Passo 4: Configurar o MauiProgram.cs

No ficheiro MauiProgram.cs da aplicação MAUI, adicione os service defaults e configure os clientes HTTP:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();

        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            });

        // Adicionar os service defaults do Aspire
        builder.AddServiceDefaults();

        // Configurar HttpClient com descoberta de serviços
        builder.Services.AddHttpClient<WeatherApiClient>(client =>
        {
            // O nome do serviço deve corresponder ao registado no App Host
            client.BaseAddress = new Uri("https+http://webapi");
        });

        return builder.Build();
    }
}

O esquema https+http:// é uma sintaxe especial que dá preferência ao HTTPS, mas faz fallback para HTTP quando necessário. O nome do serviço (webapi neste exemplo) deve corresponder exatamente ao nome usado no registo do App Host — detalhe que já me fez perder uns bons minutos depurando um problema que não existia.

Criando um Cliente Tipado para a API

Uma boa prática é criar clientes HTTP tipados para cada serviço. Honestamente, isso faz uma diferença enorme na manutenibilidade e facilita demais os testes:

public class WeatherApiClient
{
    private readonly HttpClient _httpClient;

    public WeatherApiClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<PrevisaoTempo[]?> ObterPrevisaoAsync(
        CancellationToken cancellationToken = default)
    {
        return await _httpClient.GetFromJsonAsync<PrevisaoTempo[]>(
            "/weatherforecast",
            cancellationToken);
    }
}

public record PrevisaoTempo(DateOnly Data, int TemperaturaC, string? Resumo)
{
    public int TemperaturaF => 32 + (int)(TemperaturaC * 1.8);
}

Usando o Cliente nas Páginas ou ViewModels

Injete o cliente tipado via construtor e use-o diretamente:

public partial class MainPage : ContentPage
{
    private readonly WeatherApiClient _weatherClient;

    public MainPage(WeatherApiClient weatherClient)
    {
        _weatherClient = weatherClient;
        InitializeComponent();
    }

    private async void OnObterClimaClicked(object sender, EventArgs e)
    {
        try
        {
            var previsoes = await _weatherClient.ObterPrevisaoAsync();

            if (previsoes is not null)
            {
                ResultadoLabel.Text =
                    $"Obtidas {previsoes.Length} previsões com sucesso!";

                PrevisaoCollection.ItemsSource = previsoes;
            }
        }
        catch (HttpRequestException ex)
        {
            ResultadoLabel.Text =
                $"Erro de conexão: {ex.Message}";
        }
    }
}

Comportamento Específico por Plataforma

Windows e Mac Catalyst

Nestas plataformas, a conectividade funciona diretamente via localhost. Não é necessário nenhum túnel ou configuração adicional. O Aspire simplesmente configura as URLs corretas e a descoberta de serviços funciona de forma transparente — sem surpresas.

iOS (Simulador e Dispositivo Físico)

No iOS, o Aspire configura automaticamente Dev Tunnels para permitir que o simulador ou dispositivo físico se conecte aos serviços rodando na sua máquina de desenvolvimento. Isso elimina a necessidade de configurar o Apple Transport Security (ATS) manualmente para desenvolvimento local — o que, pra quem já passou por isso, é um alívio e tanto.

Android (Emulador e Dispositivo Físico)

No Android, a integração é particularmente valiosa. Você não precisa mais de:

  • Configurar o endereço especial 10.0.2.2
  • Criar ficheiros de configuração de segurança de rede (network_security_config.xml)
  • Habilitar tráfego não criptografado para desenvolvimento local
  • Gerenciar certificados SSL manualmente

O Aspire utiliza Dev Tunnels para fornecer conectividade segura e fiável entre o emulador Android e os seus serviços locais. Simples assim.

Monitoramento e Debugging com o Dashboard do Aspire

Uma das maiores vantagens desta integração é o dashboard do Aspire, que oferece uma visão centralizada de toda a sua infraestrutura de desenvolvimento:

  • Vista de recursos: Veja todos os serviços em execução e seu estado atual.
  • Logs centralizados: Visualize logs combinados de todos os serviços num único local — app MAUI, APIs, bancos de dados.
  • Rastreamento distribuído (Traces): Acompanhe uma requisição HTTP desde a app MAUI, passando pela API, até ao banco de dados e de volta.
  • Métricas: Monitore performance, uso de recursos e latência de rede.

Para que o iOS e Android enviem dados de telemetria ao dashboard, é essencial incluir o WithOtlpDevTunnel() na configuração dos dispositivos no App Host. Sem essa configuração, as métricas e traces dessas plataformas simplesmente não aparecem no dashboard — e você vai ficar olhando pra uma tela vazia sem entender por quê.

Resolução de Problemas Comuns

A descoberta de serviços não funciona

Se a app MAUI não consegue conectar-se aos serviços web:

  1. Verifique se chamou AddServiceDefaults() no MauiProgram.cs.
  2. Confirme que o nome do serviço na configuração do HttpClient corresponde ao nome registado no App Host.
  3. Certifique-se de que está usando o esquema https+http:// na URL do serviço.
  4. Para iOS e Android, confirme que os Dev Tunnels estão configurados corretamente no App Host.

Sem métricas ou traces do iOS/Android

Se os dados de telemetria não aparecem no dashboard do Aspire:

  1. Verifique se adicionou o WithOtlpDevTunnel() às configurações de dispositivo no App Host.
  2. Confirme que o Dev Tunnel tem WithAnonymousAccess() configurado.
  3. Tente reiniciar o App Host para recriar os túneis.

Problemas de conexão com Dev Tunnels

Se os Dev Tunnels não estão funcionando:

  1. Confirme que o túnel está configurado com acesso anônimo: .WithAnonymousAccess().
  2. Verifique se a configuração do dispositivo inclui a referência ao túnel: .WithReference(weatherApi, publicDevTunnel).
  3. Certifique-se de que o firewall ou as configurações de segurança de rede não estão bloqueando as conexões do túnel.

Boas Práticas para Produção

Embora a integração com o Aspire seja focada no desenvolvimento, algumas práticas ajudam a garantir uma transição suave para produção:

  • Use clientes tipados: Crie clientes HTTP fortemente tipados para cada serviço. Isso melhora a manutenibilidade e facilita a substituição de URLs em produção.
  • Implemente tratamento de erros: Operações de rede podem falhar a qualquer momento em dispositivos móveis. Use try-catch e implemente lógica de retry com Polly.
  • Aproveite o dashboard: Use o dashboard do Aspire para identificar gargalos de performance e erros durante o desenvolvimento, antes de chegarem à produção.
  • Teste em todas as plataformas: Mesmo que a integração lide com diferenças entre plataformas, sempre teste nas plataformas alvo — emuladores e dispositivos físicos.
  • Separe configurações por ambiente: Use appsettings.json e variáveis de ambiente para gerenciar URLs de serviços em diferentes ambientes (desenvolvimento, staging, produção).

Perguntas Frequentes (FAQ)

O .NET Aspire funciona apenas com .NET MAUI 10?

Sim, a integração oficial do .NET MAUI com o Aspire está disponível a partir do .NET MAUI 10 (que faz parte do .NET 10). Para versões anteriores, é necessário configurar a conexão com serviços locais manualmente usando a abordagem tradicional documentada pela Microsoft.

Preciso do .NET Aspire em produção?

Não. O .NET Aspire é principalmente uma ferramenta de desenvolvimento local. Os Dev Tunnels são criados apenas durante o desenvolvimento e não são incluídos quando você publica ou implanta o App Host. Em produção, a sua app MAUI deve usar URLs reais configuradas através de appsettings.json ou variáveis de ambiente.

Como funciona a descoberta de serviços no .NET MAUI com Aspire?

Quando você usa o esquema https+http:// seguido do nome do serviço (ex: https+http://webapi), o Aspire resolve automaticamente esse nome para o endereço correto do serviço. No Windows/Mac, resolve para localhost com a porta correta. No iOS e Android, resolve para a URL do Dev Tunnel correspondente.

Posso usar o .NET Aspire com Blazor Hybrid no .NET MAUI?

Sim. A integração funciona perfeitamente com aplicações Blazor Hybrid no .NET MAUI. A configuração é idêntica — você registra o App Host, configura os Service Defaults e usa clientes HTTP tipados. Os componentes Blazor podem injetar os mesmos clientes tipados via injeção de dependências.

Qual é a diferença entre Dev Tunnels e o antigo 10.0.2.2 no Android?

O endereço 10.0.2.2 é um alias especial do emulador Android que aponta para o localhost da máquina host, mas exige configuração manual de segurança de rede e só funciona com emuladores. Os Dev Tunnels do Aspire criam túneis HTTPS seguros que funcionam tanto com emuladores quanto com dispositivos físicos, sem necessidade de configuração manual de rede. São mais seguros, mais fiáveis e — principalmente — muito mais fáceis de usar no dia a dia.

Sobre o Autor Editorial Team

Our team of expert writers and editors.