Template .NET Aspire avec orchestration AppHost et Gateway Ocelot pour architecture microservices.
# Installer depuis NuGet.org
dotnet new install Miccore.Net.Aspire
# Ou installer une version spécifique
dotnet new install Miccore.Net.Aspire::1.0.0# Format recommandé : Company.Service.Component
dotnet new miccore-aspire -n Acme.Ecommerce.Catalog
# Exemples de nommage :
dotnet new miccore-aspire -n Contoso.Crm.Api
dotnet new miccore-aspire -n Fabrikam.Inventory.Service
# Nom simple (aussi accepté)
dotnet new miccore-aspire -n MonProjetAcme.Ecommerce.Catalog/
├── Acme.Ecommerce.Catalog.sln
├── Acme.Ecommerce.Catalog.AppHost/
│ ├── Acme.Ecommerce.Catalog.AppHost.csproj
│ ├── Program.cs
│ └── appsettings.json
└── Acme.Ecommerce.Catalog.Gateway/
├── Acme.Ecommerce.Catalog.Gateway.csproj
├── Program.cs
├── ocelot.json
└── Configuration/
cd Acme.Ecommerce.Catalog
dotnet run --project Acme.Ecommerce.Catalog.AppHostdotnet new uninstall Miccore.Net.AspireCe guide explique comment ajouter des services provenant de différents dépôts Git à l'orchestration Aspire.
- ✅ Indépendance totale entre repos
- ✅ Chaque équipe peut déployer indépendamment
- ✅ Pas de dépendances de compilation
- ✅ CI/CD simple
- ✅ Fonctionne en local et en production
# Dans votre repo CatalogService
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY ["CatalogService.csproj", "./"]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "CatalogService.dll"]cd /path/to/CatalogService
docker build -t catalog-api:latest .
# Ou publier sur un registre
docker tag catalog-api:latest your-registry.azurecr.io/catalog-api:latest
docker push your-registry.azurecr.io/catalog-api:latestvar builder = DistributedApplication.CreateBuilder(args);
// Service distant en conteneur
var catalogService = builder.AddContainer("catalog", "catalog-api", "latest")
.WithHttpEndpoint(port: 5001, targetPort: 8080, name: "http")
.WithEnvironment("ASPNETCORE_ENVIRONMENT", builder.Environment.EnvironmentName)
.WithEnvironment("ConnectionStrings__Database", "your-connection-string");
// Gateway local
builder.AddProject<Projects.Miccore_Clean_Gateway>("Gateway")
.WithReference(catalogService);appsettings.json :
{
"Services": {
"catalog": {
"DownstreamPath": "http://catalog"
}
}
}ocelot.json :
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{everything}",
"UpstreamPathTemplate": "/catalog/{everything}",
"UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ],
"ServiceName": "catalog"
}
]
}- ✅ Débogage direct dans Visual Studio
- ✅ Hot reload fonctionne
- ✅ Pas besoin de Docker
- ❌ Nécessite checkout local de tous les repos
- ❌ Structure de dossiers rigide
- ❌ Dépendances de compilation
/Projects/
├── Aspire/ # Ce repo
│ └── Miccore.Clean.AppHost/
├── CatalogService/ # Repo séparé
│ └── src/
│ └── CatalogService.csproj
└── OrdersService/ # Repo séparé
└── src/
└── OrdersService.csproj
var catalogService = builder.AddProject("catalog",
"../../CatalogService/src/CatalogService.csproj");
var ordersService = builder.AddProject("orders",
"../../OrdersService/src/OrdersService.csproj");
builder.AddProject<Projects.Miccore_Clean_Gateway>("Gateway")
.WithReference(catalogService)
.WithReference(ordersService);- ✅ Pas besoin de Docker
- ✅ Pas de dépendances de compilation
- ❌ Nécessite publication manuelle
- ❌ Pas de débogage direct
- ❌ Pas de hot reload
cd /path/to/CatalogService
dotnet publish -c Release -o ../publish/catalogvar catalogService = builder.AddExecutable("catalog",
"../../publish/catalog/CatalogService",
"../../publish/catalog")
.WithHttpEndpoint(port: 5001)
.WithEnvironment("ASPNETCORE_URLS", "http://localhost:5001");Pour des projets existants utilisant déjà Docker Compose :
builder.AddDockerCompose("external-services", "../docker-compose.yml");| Scénario | Solution Recommandée |
|---|---|
| Production | Conteneurs Docker (Option 1) |
| Développement local (1 développeur) | Projets Externes (Option 2) |
| Équipes distribuées | Conteneurs Docker (Option 1) |
| CI/CD | Conteneurs Docker (Option 1) |
| Débogage intensif | Projets Externes (Option 2) |
Peu importe l'option choisie, la configuration de la Gateway reste identique :
{
"Services": {
"catalog": { "DownstreamPath": "http://catalog" },
"orders": { "DownstreamPath": "http://orders" },
"identity": { "DownstreamPath": "http://identity" }
}
}{
"Routes": [
{
"ServiceName": "catalog",
"UpstreamPathTemplate": "/catalog/{everything}",
"DownstreamPathTemplate": "/api/{everything}"
}
],
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Type": "AppConfiguration"
}
}
}builder.AddProject<Projects.Miccore_Clean_Gateway>("Gateway")
.WithReference(catalogService)
.WithReference(ordersService)
.WithReference(identityService);Dockerfile :
FROM mcr.microsoft.com/dotnet/aspnet:9.0
WORKDIR /app
EXPOSE 8080
COPY ./publish .
ENTRYPOINT ["dotnet", "CatalogService.dll"]Build :
dotnet publish -c Release -o ./publish
docker build -t catalog-api:dev .Program.cs :
var catalogService = builder.AddContainer("catalog", "catalog-api", "dev")
.WithHttpEndpoint(port: 5001, targetPort: 8080, name: "http");
builder.AddProject<Projects.Miccore_Clean_Gateway>("Gateway")
.WithReference(catalogService);appsettings.json :
{
"Services": {
"catalog": {
"DownstreamPath": "http://catalog"
}
}
}ocelot.json :
{
"Routes": [{
"ServiceName": "catalog",
"UpstreamPathTemplate": "/catalog/{everything}",
"DownstreamPathTemplate": "/api/{everything}",
"UpstreamHttpMethod": ["Get", "Post", "Put", "Delete"]
}]
}cd Miccore.Clean.AppHost
dotnet runAspire va :
- Démarrer le conteneur
catalog-api:devsur le port 5001 - Démarrer la Gateway
- Configurer le service discovery pour résoudre
http://catalog→http://localhost:5001 - La Gateway pourra router
/catalog/*vers le service Catalog
- Vérifiez que le nom du service correspond partout (
catalogdans cet exemple) - Vérifiez les ports exposés :
WithHttpEndpoint(targetPort: 8080) - Vérifiez que
ASPNETCORE_URLSest configuré dans le conteneur
- Assurez-vous d'utiliser
.WithReference()dans le Gateway - Vérifiez la section
Servicesdansappsettings.json - Le nom doit correspondre à celui utilisé dans
AddContainer("nom", ...)
- Normal, utilisez Option 2 (projets externes) pour le débogage intensif
- Ou configurez un volume Docker pour le hot reload