编写自定义集成
更新: 2026-10-16 15:20:09 字数: 0 字 时长: 0 分钟
当官方集成与 Community Toolkit 都没有覆盖您的资源时,可以自己写一个集成。一个「托管集成」本质上就是:
- 一个继承
Resource的类型(描述资源是什么)。 - 一组
IDistributedApplicationBuilder上的扩展方法(让用户能Add***它)。 - 可选:连接字符串支持、发布行为的自定义。
最小可用示例
假设我们要集成一个内部服务,它只需要一个地址和一个 API Key。
1. 定义资源类型
csharp
public sealed class InternalServiceResource(string name)
: Resource(name), IResourceWithConnectionString
{
public required ReferenceExpression Endpoint { get; init; }
public required IResourceBuilder<ParameterResource> ApiKey { get; init; }
public ReferenceExpression ConnectionStringExpression =>
ReferenceExpression.Create(
$"{Endpoint};ApiKey={ApiKey.Resource.ValueExpression}");
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
要点:
- 构造函数接收
name,并传给基类Resource。 - 实现
IResourceWithConnectionString后,该资源才能被WithReference消费。 - 使用
ReferenceExpression而不是直接拼字符串,可以让值在运行时解析(例如参数值在部署时才确定)。
2. 提供扩展方法
csharp
public static class InternalServiceResourceBuilderExtensions
{
public static IResourceBuilder<InternalServiceResource> AddInternalService(
this IDistributedApplicationBuilder builder,
[ResourceName] string name,
IResourceBuilder<ParameterResource>? apiKey = null)
{
var key = apiKey ?? builder.AddParameter($"{name}-api-key", secret: true);
var resource = new InternalServiceResource(name)
{
Endpoint = ReferenceExpression.Create($"https://api.internal.example.com"),
ApiKey = key
};
return builder.AddResource(resource)
.WithInitialState(new CustomResourceSnapshot
{
ResourceType = "InternalService",
State = "Running",
Properties = [new("Endpoint", "https://api.internal.example.com")]
});
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
使用时:
csharp
var internalService = builder.AddInternalService("internal-api");
builder.AddProject<Projects.Api>("api")
.WithReference(internalService);1
2
3
4
2
3
4
3. 如果需要本地容器
把上面的扩展方法改成返回容器资源即可复用 Aspire 的容器能力:
csharp
public static IResourceBuilder<InternalServiceResource> AddInternalService(
this IDistributedApplicationBuilder builder,
[ResourceName] string name)
{
return builder.AddContainer(name, "registry.example.com/internal-api:1.2.3")
.WithHttpEndpoint(targetPort: 8080)
// ...转换为自定义资源并附加注解
.WithAnnotation(new InternalServiceAnnotation());
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
让资源在仪表板上显示得更好
初始状态
通过 WithInitialState 提供资源类型、状态与自定义属性,仪表板的资源列表会展示这些信息:
csharp
builder.AddResource(myResource)
.WithInitialState(new CustomResourceSnapshot
{
ResourceType = "MyResource",
State = "Running",
Properties =
[
new("Region", "cn-east-2"),
new("Tier", "Standard")
],
Urls = [new("https://myresource.example.com", "https://myresource.example.com")]
});1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
健康检查
csharp
builder.AddResource(myResource)
.WithHealthCheck("myresource-ready");1
2
2
自定义资源命令
让用户可以在仪表板上对资源执行操作:
csharp
builder.AddResource(myResource)
.WithCommand("restart", "Restart", async context =>
{
// 执行重启逻辑
return CommandResults.Success();
});1
2
3
4
5
6
2
3
4
5
6
自定义资源 URL
csharp
builder.AddResource(myResource)
.WithUrl("https://myresource.example.com", "管理控制台");1
2
2
发布行为的自定义
如果资源需要参与发布(生成部署清单、映射到云服务),可以实现发布相关接口或通过注解描述其发布形态。关键词:
| 概念 | 用途 |
|---|---|
PublishAsConnectionString() | 发布时只输出连接字符串,不进行真正的资源映射。 |
IPublishingActivityReporter | 在发布过程中向用户报告进度。 |
ResourceSnapshot / 注解 | 为发布器提供资源的元数据。 |
先看看别人怎么写的
社区工具包里有很多体量不大的集成实现。遇到不确定的写法时,直接阅读对应仓库的源码往往比文档更快。
打包与分发
- 包名建议:自有前缀 +
Hosting,例如Contoso.Aspire.Hosting.InternalService。 - 目标框架跟随官方集成使用的 TFM(通常与当前 Aspire 主版本一致)。
- 在 README 中明确写出:支持的 Aspire 版本、资源的本地实现(容器?模拟器?)、以及发布到各平台时的映射行为。
实战建议
- 本地实现优先:一个有容器实现的自定义集成,比只能连真实服务的集成有用得多。
- 连接字符串用
ReferenceExpression:避免在构建期就固化值。 - 参数默认标记
secret: true:只要涉及密钥,默认保密。 - 不要吞掉异常:资源创建失败时应清晰抛出,Aspire 会把它呈现为
FailedToStart。





