| name | dotnet-aspire-guide |
| description | Guide .NET Aspire pour l'orchestration d'applications cloud-native, le service discovery, la télémétrie et l'intégration de composants distribués. À utiliser quand l'utilisateur travaille avec .NET Aspire, orchestre des microservices ou configure des composants cloud-native en .NET. Se déclenche aussi avec ".NET Aspire", "Aspire", "AppHost", "service discovery .NET", "orchestration cloud-native", "Aspire dashboard". |
Guide .NET Aspire
Quand utiliser .NET Aspire
| Situation | Recommandation |
|---|
| ≥ 2 services qui se parlent en local | Aspire — service discovery automatique |
| Besoin de traces distribuées dès le dev | Aspire — dashboard OTEL intégré |
| Projet mono-service simple | Aspire superflu |
| Cible Azure Container Apps / Kubernetes | Aspire — manifeste généré via azd ou aspirate |
| Équipe < 3 devs, pas de messaging | À évaluer ; Aspire a un coût d'apprentissage |
Version stable 2026 : .NET Aspire 9.x (compatible .NET 8 et .NET 9).
Étape 1 — Créer le squelette
dotnet workload install aspire
dotnet new aspire-starter -n MySolution -o MySolution
cd MySolution
Pour ajouter Aspire à une solution existante :
dotnet new aspire-apphost -n MySolution.AppHost
dotnet new aspire-servicedefaults -n MySolution.ServiceDefaults
Étape 2 — Câbler l'AppHost
L'AppHost est le point d'entrée unique. Il déclare les ressources (infra) et les projets (code), puis les relie.
var builder = DistributedApplication.CreateBuilder(args);
var postgres = builder.AddPostgres("postgres")
.WithDataVolume("pgdata")
.WithPgAdmin();
var orderDb = postgres.AddDatabase("orderdb");
var redis = builder.AddRedis("cache").WithRedisCommander();
var bus = builder.AddRabbitMQ("messaging").WithManagementPlugin();
var api = builder.AddProject<Projects.MySolution_ApiService>("api")
.WithReference(orderDb)
.WithReference(redis)
.WithReference(bus)
.WithReplicas(2);
builder.AddProject<Projects.MySolution_Web>("web")
.WithExternalHttpEndpoints()
.WithReference(api);
builder.Build().Run();
Règle : nommez les ressources en minuscules-tirets ("order-db"), ce nom devient la clé de service discovery.
Étape 3 — ServiceDefaults (configuration partagée)
Chaque service appelle AddServiceDefaults() dans son Program.cs. Ce package centralise : OpenTelemetry, health checks, resilience, service discovery.
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
public static IHostApplicationBuilder AddServiceDefaults(
this IHostApplicationBuilder builder)
{
builder.ConfigureOpenTelemetry();
builder.AddDefaultHealthChecks();
builder.Services.AddServiceDiscovery();
builder.Services.ConfigureHttpClientDefaults(http =>
{
http.AddStandardResilienceHandler();
http.AddServiceDiscovery();
});
return builder;
}
public static IHostApplicationBuilder ConfigureOpenTelemetry(
this IHostApplicationBuilder builder)
{
builder.Logging.AddOpenTelemetry(o =>
{
o.IncludeFormattedMessage = true;
o.IncludeScopes = true;
});
builder.Services.AddOpenTelemetry()
.WithMetrics(m => m
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation())
.WithTracing(t => t
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddEntityFrameworkCoreInstrumentation());
builder.AddOpenTelemetryExporters();
return builder;
}
Étape 4 — Service Discovery dans les services
builder.Services.AddHttpClient<IOrderServiceClient>(client =>
{
client.BaseAddress = new Uri("https+http://api");
});
builder.AddNpgsqlDataSource("orderdb");
Composants intégrés (Aspire 9)
| Technologie | Package NuGet (AppHost) | Package NuGet (Service) | Méthode service |
|---|
| PostgreSQL | Aspire.Hosting.PostgreSQL | Aspire.Npgsql | AddNpgsqlDataSource |
| SQL Server | Aspire.Hosting.SqlServer | Aspire.Microsoft.Data.SqlClient | AddSqlServerClient |
| Redis | Aspire.Hosting.Redis | Aspire.StackExchange.Redis | AddRedisClient |
| RabbitMQ | Aspire.Hosting.RabbitMQ | Aspire.RabbitMQ.Client | AddRabbitMQClient |
| MongoDB | Aspire.Hosting.MongoDB | Aspire.MongoDB.Driver | AddMongoDBClient |
| Kafka | Aspire.Hosting.Kafka | Aspire.Confluent.Kafka | AddKafkaProducer |
| Azure Blob | Aspire.Hosting.Azure.Storage | Aspire.Azure.Storage.Blobs | AddAzureBlobClient |
| Azure Service Bus | Aspire.Hosting.Azure.ServiceBus | Aspire.Azure.Messaging.ServiceBus | AddAzureServiceBusClient |
| Elasticsearch | Aspire.Hosting.Elasticsearch | Aspire.Elastic.Clients.Elasticsearch | AddElasticsearchClient |
Étape 5 — Dashboard Aspire
Lancé automatiquement avec dotnet run sur l'AppHost :
| Vue | Usage |
|---|
| Resources | État (Running/Stopped/Unhealthy) de chaque conteneur/projet |
| Console Logs | Stdout/stderr en temps réel, filtrable par service |
| Structured Logs | Logs JSON avec filtres sur niveau/message/attributs |
| Traces | Traces distribuées OTEL — waterfall inter-services |
| Metrics | Métriques runtime + applicatives (graphs) |
URL par défaut : https://localhost:17088 (token dans la console au démarrage).
Étape 6 — Déploiement
Azure Container Apps (recommandé)
dotnet tool install -g azd
azd init
azd up
Kubernetes (via Aspirate)
dotnet tool install -g aspirate
aspirate init
aspirate generate
aspirate apply
Production : remplacer les conteneurs locaux par des services managés
if (builder.ExecutionContext.IsPublishMode)
{
var sql = builder.AddAzureSqlServer("sql")
.AddDatabase("orderdb");
}
else
{
var sql = builder.AddSqlServer("sql")
.AddDatabase("orderdb");
}
Anti-patterns / Pièges
| Problème | Cause | Correction |
|---|
| Service discovery échoue | Nom dans AddHttpClient ne correspond pas au nom AppHost | Utiliser exactement le même nom logique |
| Port déjà utilisé au démarrage | Aspire affecte des ports dynamiques mais les profils launchSettings peuvent fixer les ports | Supprimer les applicationUrl dans launchSettings.json des services |
| Données perdues entre redémarrages | Volume anonyme (sans .WithDataVolume("nom")) | Toujours nommer les volumes |
| Traces manquantes | AddServiceDefaults() non appelé dans un service | Vérifier que chaque service l'appelle |
| Container pull lent en CI | Images téléchargées à chaque run | Pré-pull les images dans le step CI ou utiliser un registry miroir |
WithReplicas en prod | Les réplicas Aspire sont pour le dev uniquement | En prod, déléguer le scaling à ACA/K8s |
| Secrets en clair dans AppHost | .WithEnvironment("API_KEY", "secret") visible dans les logs Aspire | Utiliser builder.AddParameter("api-key", secret: true) |
Bonnes pratiques 2026