创建自定义 .NET Aspire 托管集成

本文详细介绍了如何为 .NET Aspire 构建自定义托管集成,以 MailDev(一款开源邮件测试工具)为例,演示了从项目设置到验证使用的完整流程。

核心概念

.NET Aspire 中的自定义资源需包含两个关键元素:

  • 实现 IResource 的自定义资源类型
  • IDistributedApplicationBuilder 提供的扩展方法(命名格式为 Add{CustomResource}

通过这些元素,开发者可像使用内置资源(如 Redis、Postgres)一样,通过简洁代码将自定义资源添加到应用模型中。

实现步骤(以 MailDev 为例)

1. 项目设置

创建基础的 .NET Aspire 项目结构,包括应用主机(AppHost)和服务默认项目:

dotnet new aspire -o MailDevResource
cd MailDevResource

2. 创建资源扩展库

专门的类库用于存放自定义资源逻辑:

# 创建类库
dotnet new classlib -o MailDev.Hosting
# 添加 Aspire.Hosting 依赖
dotnet add ./MailDev.Hosting/MailDev.Hosting.csproj package Aspire.Hosting --version 9.0.0
# 关联到应用主机
dotnet add ./MailDevResource.AppHost reference ./MailDev.Hosting

3. 定义资源类型

实现 MailDevResource 类,继承容器资源并提供连接字符串:

namespace Aspire.Hosting.ApplicationModel;

public sealed class MailDevResource(string name) : ContainerResource(name), IResourceWithConnectionString
{
    internal const string SmtpEndpointName = "smtp";
    internal const string HttpEndpointName = "http";

    private EndpointReference? _smtpReference;
    public EndpointReference SmtpEndpoint => _smtpReference ??= new(this, SmtpEndpointName);

    // 定义连接字符串表达式
    public ReferenceExpression ConnectionStringExpression =>
        ReferenceExpression.Create($"smtp://{SmtpEndpoint.Property(EndpointProperty.HostAndPort)}");
}

4. 定义资源扩展方法

提供 AddMailDev 扩展方法,简化资源添加流程:

public static class MailDevResourceBuilderExtensions
{
    public static IResourceBuilder<MailDevResource> AddMailDev(
        this IDistributedApplicationBuilder builder,
        string name,
        int? httpPort = null,
        int? smtpPort = null)
    {
        var resource = new MailDevResource(name);
        return builder.AddResource(resource)
                      .WithImage("maildev/maildev")
                      .WithImageTag("LATEST")
                      .WithHttpEndpoint(targetPort: 1080, name: MailDevResource.HttpEndpointName)
                      .WithEndpoint(targetPort: 1025, name: MailDevResource.SmtpEndpointName);
    }
}

5. 验证与使用

在应用主机中添加并使用自定义资源:

// MailDevResource.AppHost/Program.cs
var builder = DistributedApplication.CreateBuilder(args);
var maildev = builder.AddMailDev("maildev"); // 使用自定义资源
builder.Build().Run();

启动后,通过 .NET Aspire 仪表板可查看运行的 MailDev 资源,并通过连接字符串在服务中发送测试邮件:

// 在服务项目中注入 SmtpClient
builder.Services.AddSingleton<SmtpClient>(sp =>
{
    var smtpUri = new Uri(builder.Configuration.GetConnectionString("maildev")!);
    return new SmtpClient(smtpUri.Host, smtpUri.Port);
});

app.MapGet("/subscribe", async ([FromServices]SmtpClient smtpClient, [FromQuery]string email) =>
{
    using var message = new MailMessage("newsletter@yourcompany.com", email)
    {
        Subject = "Welcome to our newsletter!",
        Body = "Thank you for subscribing to our newsletter!"
    };

    await smtpClient.SendMailAsync(message);
});

app.MapGet("/unsubscribe", async ([FromServices] SmtpClient smtpClient, [FromQuery] string email) =>
{
    using var message = new MailMessage("newsletter@yourcompany.com", email)
    {
        Subject = "You are unsubscribed from our newsletter!",
        Body = "Sorry to see you go. We hope you will come back soon!"
    };

    await smtpClient.SendMailAsync(message);
});
# 启动 aspire ,并访问该地址
http://localhost:5174/subscribe?email=test@test1.com
http://localhost:5174/unsubscribe?email=test@test1.com

在这里插入图片描述
在这里插入图片描述

关键技术点

  • ReferenceExpressionEndpointReference:用于延迟解析配置信息(如端口、主机),直到运行时或部署时才能确定具体值。
  • 清单发布:通过 dotnet run -- --publisher manifest 生成部署清单,包含资源间的依赖关系和连接信息。
  • 安全性:需考虑资源的网络暴露范围,避免敏感信息泄露(如生产环境需配置 HTTPS)。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐