.NETAspire集成技能Skill dotnet-aspire

.NET Aspire 集成技能用于为现有 .NET 解决方案添加云原生编排,或创建新的分布式应用程序。它提供服务发现、配置管理、可观测性等功能,适用于微服务和云原生架构开发。关键词:.NET Aspire、云原生、微服务、服务发现、配置管理、分布式应用。

云原生架构 0 次安装 0 次浏览 更新于 3/22/2026

名称: dotnet-aspire 描述: 为现有 .NET 解决方案添加 .NET Aspire 云原生编排。分析解决方案结构以识别服务(APIs、web 应用、工作者),创建 AppHost 和 ServiceDefaults 项目,配置服务发现,添加 NuGet 包,并设置分布式应用程序编排。适用于将 Aspire 添加到 .NET 解决方案或创建新的云就绪分布式应用程序。 许可证: MIT 元数据: 版本: “2.0” 领域: 基础设施 触发词: Aspire, .NET Aspire, AppHost, ServiceDefaults, 服务发现, 云原生, 分布式应用, 编排, 遥测, 可观测性 角色: 专家 范围: 实施 输出格式: 代码 相关技能: dotnet-core-expert, microservices-architect, kubernetes-specialist

.NET Aspire 集成技能

此技能帮助将 .NET Aspire 添加到现有 .NET 解决方案或创建新的 Aspire 支持的分布式应用程序。它提供模块化指导,涵盖编排、服务发现、组件集成、配置管理和部署。

什么是 .NET Aspire?

.NET Aspire 是一个用于构建可观测、生产就绪、分布式应用程序的云就绪堆栈。它提供:

  • 服务编排 - 通过依赖管理协调多个项目和服务
  • 服务发现 - 服务之间的自动发现和连接
  • 遥测和可观测性 - 内置的日志记录、指标和分布式追踪
  • 配置管理 - 通过强类型和机密的集中式配置
  • 资源供应 - 与数据库、缓存、消息传递和云服务的集成
  • 开发者仪表板 - 本地监控和调试界面

何时使用此技能

在以下情况下使用此技能:

  • 将 Aspire 添加到具有多个服务的现有 .NET 解决方案中
  • 使用 Aspire 创建新的分布式应用程序
  • 为云部署现代化微服务或分布式系统
  • 为本地开发和部署设置服务编排
  • 集成云原生可观测性和配置模式

我需要什么组件/功能?

需求 资源 描述
整体结构 概述与设置 从分析到运行的分步实施
数据库、缓存、消息传递 resources/components.md 所有可用的 Aspire 组件包及示例
服务间通信 resources/service-communication.md 服务发现、HttpClient 模式、弹性
配置与机密 resources/configuration-management.md 环境设置、机密、功能标志
本地开发 resources/local-development.md 仪表板、调试、测试、健康检查
生产部署 resources/deployment.md Azure 容器应用、Kubernetes、Docker Compose

概述与设置

核心概念

.NET Aspire 使用两个关键项目:

  • AppHost - 编排服务和资源;提供开发者仪表板
  • ServiceDefaults - 所有服务的共享配置(OpenTelemetry、健康检查、服务发现)

先决条件

# 安装 .NET Aspire 工作负载
dotnet workload install aspire

# 验证安装
dotnet workload list  # 应显示 "aspire"

# Docker Desktop(用于容器资源)
# 在启动 AppHost 前确保其运行

基本实施流程

1. 分析解决方案

  • 识别服务(APIs、web 应用、工作者)
  • 列出外部依赖(数据库、Redis、消息队列)
  • 确定服务通信模式

2. 创建 Aspire 项目

dotnet new aspire-apphost -n MyApp.AppHost
dotnet new aspire-servicedefaults -n MyApp.ServiceDefaults
dotnet sln add MyApp.AppHost/MyApp.AppHost.csproj
dotnet sln add MyApp.ServiceDefaults/MyApp.ServiceDefaults.csproj

3. 配置服务

  • 为每个服务添加 ServiceDefaults 引用
  • 在 Program.cs 中调用 builder.AddServiceDefaults()
  • ASP.NET Core 服务调用 app.MapDefaultEndpoints()

4. 在 AppHost 中编排

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");
var database = builder.AddPostgres("postgres").AddDatabase("appdb");

var api = builder.AddProject<Projects.MyApi>("api")
    .WithReference(database)
    .WithReference(cache);

var web = builder.AddProject<Projects.MyWeb>("web")
    .WithReference(api)
    .WithExternalHttpEndpoints();

builder.Build().Run();

5. 更新服务通信

  • 将硬编码的 URL 替换为服务名称
  • 使用 builder.AddServiceDefaults() 模式匹配

6. 运行和验证

dotnet run --project MyApp.AppHost
# 在 https://localhost:15001 打开仪表板

关键决策

AppHost 项目命名:

  • 惯例:[解决方案名称].AppHost
  • 示例:对于解决方案 “ECommerceSystem”,创建 “ECommerceSystem.AppHost”

服务资源名称:

  • 在 AppHost 中使用简短、描述性的名称
  • 示例:“api”、“web”、“worker”、“cache”、“database”
  • 这些名称用于服务发现 URL

资源管理:

  • 本地开发:使用 Aspire 管理的容器(PostgreSQL、Redis、RabbitMQ)
  • 生产:通过 azd 自动配置 Azure 资源或手动配置
  • 连接字符串:自动注入;很少需要硬编码

服务发现设置:

  • HttpClient URL 使用服务名称:http://api 而不是 https://localhost:7001
  • Aspire 处理服务之间的路由和身份验证
  • 外部服务使用显式端点配置

常见架构

Web API + 前端

var api = builder.AddProject<Projects.Api>("api")
    .WithReference(database)
    .WithExternalHttpEndpoints();

var web = builder.AddProject<Projects.Web>("web")
    .WithReference(api)
    .WithExternalHttpEndpoints();

带有消息队列的微服务

var messaging = builder.AddRabbitMQ("messaging");

var orderService = builder.AddProject<Projects.OrderService>("orders")
    .WithReference(messaging);

var inventoryService = builder.AddProject<Projects.InventoryService>("inventory")
    .WithReference(messaging);

多数据库系统

var postgres = builder.AddPostgres("postgres")
    .AddDatabase("users")
    .AddDatabase("products");

var mongo = builder.AddMongoDB("mongo")
    .AddDatabase("orders");

var userApi = builder.AddProject<Projects.UserApi>("userapi")
    .WithReference(postgres);

var orderApi = builder.AddProject<Projects.OrderApi>("orderapi")
    .WithReference(mongo);

资源索引

有关详细实施指导,请参见:

  • 组件 - 组件包和集成模式:resources/components.md
  • 服务通信 - 服务发现和跨服务调用:resources/service-communication.md
  • 配置管理 - 机密、环境变量、设置:resources/configuration-management.md
  • 本地开发 - 仪表板功能、调试、健康检查:resources/local-development.md
  • 部署 - Azure 容器应用、Kubernetes、Docker Compose:resources/deployment.md

最佳实践

服务组织

  • 保持 AppHost 专注于组合,而非业务逻辑
  • 使用 ServiceDefaults 处理横切关注点(可观测性、健康检查)
  • 确保每个服务独立运行,具有后备配置

资源管理

  • 使用 Aspire 管理的资源确保本地开发一致性
  • 通过 .WithReference() 在 AppHost 中定义显式依赖
  • 为数据库添加数据持久化:.WithDataVolume()

配置模式

  • 开发:使用 appsettings.Development.json.WithEnvironment()
  • 生产:使用 Azure Key Vault 或托管机密
  • 避免在源代码中存储机密;本地使用用户机密

可观测服务

  • 通过 ServiceDefaults 启用 OpenTelemetry(自动)
  • 使用开发者仪表板进行本地调试
  • 在生产中将遥测导出到 Application Insights 或类似工具

常见问题与解决方案

服务无法通信

  • 验证 AppHost 中的服务名称是否与 HttpClient URL 匹配
  • 确保在所有服务中调用 AddServiceDefaults()
  • 检查 ASP.NET 服务是否调用 MapDefaultEndpoints()

连接字符串未注入

  • 使用 builder.AddNpgsqlDbContext<>() 而非手动配置
  • 验证数据库/资源名称在 AppHost 和服务中是否匹配
  • 确认项目文件中存在 ServiceDefaults 引用

仪表板无法启动

  • 确保 Docker Desktop 正在运行
  • 检查端口冲突(默认:15001)
  • 验证 AppHost 项目运行,而非单个服务

健康检查失败

  • 在仪表板中查看资源启动日志
  • 检查本地机器上的端口可用性
  • 验证 Docker 有足够的资源

入门清单

  • [ ] 安装 .NET Aspire 工作负载并验证
  • [ ] 分析解决方案结构并识别服务
  • [ ] 创建 AppHost 和 ServiceDefaults 项目
  • [ ] 为每个服务添加 ServiceDefaults 引用
  • [ ] 使用 AddServiceDefaults()MapDefaultEndpoints() 更新服务 Program.cs
  • [ ] 使用服务和资源配置 AppHost 编排
  • [ ] 将服务 HttpClient URL 更新为使用服务发现名称
  • [ ] 使用 dotnet run --project AppHost 本地测试
  • [ ] 验证仪表板显示所有服务正在运行
  • [ ] 配置部署目标(Azure、Kubernetes 等)

后续步骤

  1. 有关组件详情 → 参见 resources/components.md
  2. 有关服务通信 → 参见 resources/service-communication.md
  3. 有关配置 → 参见 resources/configuration-management.md
  4. 有关本地开发 → 参见 resources/local-development.md
  5. 有关部署 → 参见 resources/deployment.md

记住:从单个服务开始,验证通信正常,然后添加复杂性。在部署到生产之前,使用仪表板调试本地问题。

  1. 哪些项目应被编排为服务?
  2. 需要哪些外部资源(数据库、Redis、存储等)?
  3. 应该使用最小 Aspire 设置还是包括额外组件?
  4. 是否有任何现有的 Docker 或编排配置?

2. 澄清问题

在实施前,与用户确认:

服务识别:

  • “我已识别出解决方案中的 [X] 个服务:[列表]。是否所有这些都应包含在 Aspire 编排中?”
  • “是否有任何额外的服务或项目应被添加?”

基础设施需求:

  • “我看到对 [数据库/Redis/等] 的引用。是否应由 Aspire 管理这些资源?”
  • “您希望使用容器资源还是连接字符串配置?”

Aspire 结构:

  • “我应该创建一个名为 ‘[解决方案名称].AppHost’ 的新 AppHost 项目和名为 ‘[解决方案名称].ServiceDefaults’ 的 ServiceDefaults 项目吗?”
  • “您偏好特定的命名惯例吗?”

依赖关系:

  • “哪些服务相互依赖?(这有助于设置服务发现)”
  • “是否有任何启动顺序要求?”

3. 实施步骤

步骤 1:创建 Aspire 项目

创建 AppHost 项目:

dotnet new aspire-apphost -n [解决方案名称].AppHost

AppHost 项目:

  • 编排所有服务和资源
  • 定义服务依赖和配置
  • 为本地开发提供开发者仪表板
  • 包含应用程序组合的 Program.cs

创建 ServiceDefaults 项目:

dotnet new aspire-servicedefaults -n [解决方案名称].ServiceDefaults

ServiceDefaults 项目:

  • 提供共享服务配置
  • 配置 OpenTelemetry、健康检查和服务发现
  • 应用于所有服务以确保一致行为

将项目添加到解决方案:

dotnet sln add [解决方案名称].AppHost/[解决方案名称].AppHost.csproj
dotnet sln add [解决方案名称].ServiceDefaults/[解决方案名称].ServiceDefaults.csproj

步骤 2:配置服务项目

对于每个服务项目(API、Web 应用、工作者):

  1. 添加 ServiceDefaults 引用:
dotnet add [服务项目] reference [解决方案名称].ServiceDefaults/[解决方案名称].ServiceDefaults.csproj
  1. 更新 Program.cs 以注册服务默认值:
// 在 Program.cs 顶部,构建器创建后
var builder = WebApplication.CreateBuilder(args);

// 添加此行
builder.AddServiceDefaults();

// ... 服务配置的其余部分 ...

var app = builder.Build();

// 在 app.Run() 前添加此行
app.MapDefaultEndpoints();

app.Run();
  1. 对于工作者服务,模式类似:
var builder = Host.CreateApplicationBuilder(args);

builder.AddServiceDefaults();

// ... 服务配置 ...

var host = builder.Build();
host.Run();

步骤 3:配置 AppHost

在 AppHost 中添加项目引用:

dotnet add [解决方案名称].AppHost reference [服务项目1]/[服务项目1].csproj
dotnet add [解决方案名称].AppHost reference [服务项目2]/[服务项目2].csproj

更新 AppHost Program.cs 以编排服务:

var builder = DistributedApplication.CreateBuilder(args);

// 添加基础设施资源
var cache = builder.AddRedis("cache");
var postgres = builder.AddPostgres("postgres")
    .AddDatabase("appdb");

// 添加带依赖的服务
var apiService = builder.AddProject<Projects.MyApi>("apiservice")
    .WithReference(postgres)
    .WithReference(cache);

var webApp = builder.AddProject<Projects.MyWebApp>("webapp")
    .WithReference(apiService)
    .WithExternalHttpEndpoints();

builder.Build().Run();

常见资源方法:

  • .AddRedis("名称") - Redis 缓存
  • .AddPostgres("名称").AddDatabase("数据库名") - PostgreSQL
  • .AddSqlServer("名称").AddDatabase("数据库名") - SQL Server
  • .AddRabbitMQ("名称") - RabbitMQ 消息传递
  • .AddMongoDB("名称").AddDatabase("数据库名") - MongoDB
  • .AddAzureStorage("名称") - Azure 存储

服务配置方法:

  • .WithReference(资源) - 添加依赖并注入连接信息
  • .WithExternalHttpEndpoints() - 使服务可从外部访问
  • .WithReplicas(数量) - 运行多个实例
  • .WithEnvironment("键", "值") - 添加环境变量
  • .WithHttpsEndpoint(端口: 7001) - 指定 HTTPS 端口

步骤 4:添加所需的 NuGet 包

模板自动添加 Aspire 包,但验证:

AppHost 项目:

  • Aspire.Hosting.AppHost(通常通过工作负载包含)
  • 资源的额外托管包(例如,Aspire.Hosting.PostgreSQL

ServiceDefaults 项目:

  • Microsoft.Extensions.Http.Resilience
  • Microsoft.Extensions.ServiceDiscovery
  • OpenTelemetry.Exporter.OpenTelemetryProtocol
  • OpenTelemetry.Extensions.Hosting
  • OpenTelemetry.Instrumentation.AspNetCore
  • OpenTelemetry.Instrumentation.Http
  • OpenTelemetry.Instrumentation.Runtime

服务项目:

  • Aspire.Npgsql.EntityFrameworkCore.PostgreSQL(如果使用 PostgreSQL)
  • Aspire.StackExchange.Redis(如果使用 Redis)
  • 数据库、消息传递等的组件包,根据需要

安装包:

dotnet add [项目] package [包名]

步骤 5:更新服务通信

对于调用其他服务的服务,使用服务发现:

之前(硬编码 URL):

builder.Services.AddHttpClient("apiservice", client =>
{
    client.BaseAddress = new Uri("https://localhost:7001");
});

之后(服务发现):

builder.Services.AddHttpClient("apiservice", client =>
{
    client.BaseAddress = new Uri("http://apiservice");
});

服务名称与 AppHost 中 AddProject<>() 调用的名称匹配。

对于类型化 HttpClients:

builder.Services.AddHttpClient<IApiClient, ApiClient>(client =>
{
    client.BaseAddress = new Uri("http://apiservice");
});

步骤 6:配置和连接字符串

资源连接字符串自动注入。更新服务配置:

之前:

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));

之后:

builder.AddNpgsqlDbContext<AppDbContext>("appdb");

连接名称(“appdb”)与 AppHost 中的数据库名称匹配。

对于 Redis:

builder.AddRedisClient("cache");

步骤 7:验证和测试

运行 AppHost 项目:

dotnet run --project [解决方案名称].AppHost

这会启动:

  • Aspire 仪表板(通常在 https://localhost:15001
  • 所有配置的服务
  • 任何资源容器(Redis、PostgreSQL 等)

验证:

  1. 仪表板显示所有服务正在运行
  2. 服务可以通过服务发现通信
  3. 遥测数据出现在仪表板中
  4. 资源连接正常工作

4. 高级配置

外部服务

对于不在解决方案中的服务:

var externalApi = builder.AddProject<Projects.ExternalApi>("external-api")
    .WithHttpsEndpoint(port: 8001);

容器资源

在容器中运行服务:

var myApi = builder.AddContainer("myapi", "myapiimage")
    .WithHttpEndpoint(port: 8000, targetPort: 80);

Azure 资源

对于 Azure 托管的资源:

var storage = builder.AddAzureStorage("storage")
    .AddBlobs("blobs");

var keyVault = builder.AddAzureKeyVault("keyvault");

自定义资源

使用自定义资源扩展 Aspire:

var customResource = builder.AddResource(new CustomResource("name"))
    .WithEndpoint("http", endpoint => endpoint.Port = 9000);

最佳实践

1. 服务组织

  • 保持 AppHost 专注于编排,而非业务逻辑
  • 使用 ServiceDefaults 处理横切关注点
  • 确保每个服务独立运行(具有后备配置)

2. 资源管理

  • 使用 Aspire 管理的资源进行本地开发
  • 使用连接字符串进行生产部署
  • 为数据库配置资源持久化(避免数据丢失)

3. 配置

  • 使用 appsettings.Development.json 进行本地覆盖
  • 将敏感数据保存在用户机密或密钥保管库中
  • 使用环境特定配置

4. 依赖关系

  • 在 AppHost 中定义显式服务依赖
  • 使用 .WithReference() 注入连接信息
  • 考虑数据库迁移的启动顺序

5. 可观测性

  • 利用内置 OpenTelemetry 进行分布式追踪
  • 使用仪表板进行本地调试
  • 为每个服务配置适当的日志级别

常见模式

API 网关模式

var apiGateway = builder.AddProject<Projects.ApiGateway>("gateway")
    .WithExternalHttpEndpoints();

var serviceA = builder.AddProject<Projects.ServiceA>("servicea");
var serviceB = builder.AddProject<Projects.ServiceB>("serviceb");

apiGateway.WithReference(serviceA).WithReference(serviceB);

带有消息队列的工作者

var messaging = builder.AddRabbitMQ("messaging");

var worker = builder.AddProject<Projects.Worker>("worker")
    .WithReference(messaging);

var api = builder.AddProject<Projects.Api>("api")
    .WithReference(messaging);

Web 应用与后端 API

var cache = builder.AddRedis("cache");
var database = builder.AddPostgres("postgres").AddDatabase("appdb");

var api = builder.AddProject<Projects.Api>("api")
    .WithReference(database)
    .WithReference(cache);

var web = builder.AddProject<Projects.Web>("web")
    .WithReference(api)
    .WithExternalHttpEndpoints();

故障排除

服务发现不工作

  • 确保在服务 Program.cs 中调用 builder.AddServiceDefaults()
  • 验证 HttpClient 中的服务名称是否与 AppHost AddProject 名称匹配
  • 检查 ASP.NET 服务是否调用 app.MapDefaultEndpoints()

连接字符串未注入

  • 确认资源名称在 AppHost 和服务配置中匹配
  • 使用 builder.AddNpgsqlDbContext<>() 而非手动 AddDbContext
  • 验证 ServiceDefaults 引用是否存在

仪表板无法访问

  • 检查 AppHost 是否正在运行(而非单个服务)
  • 验证端口未被阻止(默认:15001)
  • 查看 AppHost 控制台输出中的仪表板 URL

资源无法启动

  • 确保 Docker Desktop 正在运行(对于容器资源)
  • 检查与现有服务的端口冲突
  • 查看 AppHost 控制台中的启动错误

要修改的文件

将 Aspire 添加到现有解决方案时,预计修改:

  1. 解决方案文件 (.sln) - 添加 AppHost 和 ServiceDefaults 项目
  2. 每个服务的 Program.cs - 添加服务默认值注册
  3. 每个服务的 .csproj - 添加 ServiceDefaults 引用
  4. AppHost/Program.cs - 定义编排和资源
  5. 服务配置 - 将硬编码 URL 替换为服务发现
  6. 数据库配置 - 使用 Aspire 组件方法

先决条件

确保已安装以下内容:

  • .NET 8.0 SDK 或更高版本
  • .NET Aspire 工作负载:dotnet workload install aspire
  • Docker Desktop(用于容器资源)

验证安装:

dotnet workload list

应显示 “aspire” 在已安装的工作负载中。

总结清单

实施 Aspire 后,验证:

  • [ ] AppHost 项目已创建并添加到解决方案
  • [ ] ServiceDefaults 项目已创建并添加到解决方案
  • [ ] 所有服务项目引用 ServiceDefaults
  • [ ] 服务 Program.cs 文件调用 AddServiceDefaults()MapDefaultEndpoints()
  • [ ] AppHost Program.cs 编排所有服务,具有适当的依赖关系
  • [ ] 服务间通信使用服务发现(而非硬编码 URL)
  • [ ] 数据库和缓存连接使用 Aspire 组件方法
  • [ ] AppHost 成功运行并启动仪表板
  • [ ] 所有服务出现在仪表板中并显示健康状态
  • [ ] 跨服务的请求遥测数据出现

附加资源

有关特定组件和模式的详细信息,请参见:

  • resources/components.md - Aspire 组件包和配置
  • resources/deployment.md - 将 Aspire 应用程序部署到生产环境

示例输出

完成后,解决方案结构应如下所示:

MySolution/
├── MySolution.sln
├── MySolution.AppHost/
│   ├── Program.cs                 # 编排配置
│   ├── MySolution.AppHost.csproj
│   └── appsettings.json
├── MySolution.ServiceDefaults/
│   ├── Extensions.cs              # 服务默认值实现
│   └── MySolution.ServiceDefaults.csproj
├── MySolution.Api/
│   ├── Program.cs                 # 调用 AddServiceDefaults()
│   └── MySolution.Api.csproj      # 引用 ServiceDefaults
├── MySolution.Web/
│   ├── Program.cs                 # 调用 AddServiceDefaults()
│   └── MySolution.Web.csproj      # 引用 ServiceDefaults
└── MySolution.Worker/
    ├── Program.cs                 # 调用 AddServiceDefaults()
    └── MySolution.Worker.csproj   # 引用 ServiceDefaults

运行 dotnet run --project MySolution.AppHost 启动所有服务并打开仪表板,以监控和调试分布式应用程序。