You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将MassTransit抽象到类库:跨项目添加消费者的实现疑问

解决MassTransit类库添加外部项目消费者的方案

下面给你三种可行的实现方式,完全不用让类库反向引用Worker或Web项目:

1. 给CreateBus方法添加自定义配置委托

直接在类库的RabbitMQBusFactory里给CreateBus加一个委托参数,让调用方(Worker/Web项目)自己传入消费者的注册逻辑。

修改后的类库代码:

public class RabbitMQBusFactory
{
    public static IBusControl CreateBus(
        string rabbitMQUrl, 
        string rabbitMQUser, 
        string rabbitMQPassword,
        // 新增委托参数,允许外部项目自定义总线配置
        Action<IRabbitMqBusFactoryConfigurator, IRabbitMqHost> configureBus = null)
    {
        var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
        {
            var host = cfg.Host(new Uri(rabbitMQUrl), hostConfig =>
            {
                hostConfig.Username(rabbitMQUser);
                hostConfig.Password(rabbitMQPassword);
            });

            // 执行类库默认的端点配置
            cfg.ConfigureEndpoints(host);

            // 如果外部传入了配置逻辑,执行它(注册消费者等操作)
            configureBus?.Invoke(cfg, host);
        });

        return busControl;
    }
}

Worker/Web项目里的调用示例:

// 假设Worker项目中有MyMessageConsumer消费者类
var bus = RabbitMQBusFactory.CreateBus(
    "rabbitmq://localhost",
    "guest",
    "guest",
    (cfg, host) =>
    {
        // 注册当前项目的消费者到总线
        cfg.ReceiveEndpoint(host, "my-message-queue", e =>
        {
            e.Consumer<MyMessageConsumer>();
        });
    });

2. 通过程序集扫描自动加载消费者

如果消费者类都实现了IConsumer接口,可以让类库扫描指定程序集,自动注册里面的所有消费者。

修改类库的CreateBus方法,支持传入包含消费者的程序集:

public class RabbitMQBusFactory
{
    public static IBusControl CreateBus(
        string rabbitMQUrl, 
        string rabbitMQUser, 
        string rabbitMQPassword,
        params Assembly[] consumerAssemblies)
    {
        var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
        {
            var host = cfg.Host(new Uri(rabbitMQUrl), hostConfig =>
            {
                hostConfig.Username(rabbitMQUser);
                hostConfig.Password(rabbitMQPassword);
            });

            cfg.ConfigureEndpoints(host);

            // 遍历传入的程序集,自动扫描并注册所有消费者
            foreach (var assembly in consumerAssemblies)
            {
                // 直接注册消费者
                cfg.Consumer(assembly);
                // 或者用约定式端点配置,自动生成队列名称
                cfg.ConfigureEndpoints(host, new KebabCaseEndpointNameFormatter(), x =>
                {
                    x.IncludeNamespace = false;
                    x.AddConsumers(assembly);
                });
            }
        });

        return busControl;
    }
}

Worker项目调用示例:

// 传入当前项目的程序集,类库会自动扫描里面的消费者
var bus = RabbitMQBusFactory.CreateBus(
    "rabbitmq://localhost",
    "guest",
    "guest",
    typeof(MyMessageConsumer).Assembly);

3. 结合依赖注入扩展(适合使用DI的场景)

如果你的项目用了依赖注入,可以在类库中提供DI扩展方法,让调用项目先把消费者注册到DI容器,再通过DI完成总线配置。

类库中添加DI扩展:

public static class MassTransitDependencyInjectionExtensions
{
    public static IServiceCollection AddRabbitMQBus(
        this IServiceCollection services,
        string rabbitMQUrl, 
        string rabbitMQUser, 
        string rabbitMQPassword)
    {
        services.AddMassTransit(config =>
        {
            // 类库这里不注册消费者,留待调用项目自行添加
            config.UsingRabbitMq((ctx, cfg) =>
            {
                cfg.Host(new Uri(rabbitMQUrl), h =>
                {
                    h.Username(rabbitMQUser);
                    h.Password(rabbitMQPassword);
                });

                cfg.ConfigureEndpoints(ctx);
            });
        });

        return services;
    }
}

Worker项目的Program.cs里注册示例:

var builder = Host.CreateDefaultBuilder(args);
builder.ConfigureServices(services =>
{
    // 先调用类库的DI扩展配置总线基础信息
    services.AddRabbitMQBus(
        "rabbitmq://localhost",
        "guest",
        "guest");

    // 注册当前项目的消费者到DI容器
    services.AddMassTransit(config =>
    {
        config.AddConsumer<MyMessageConsumer>();
    });
});

内容的提问来源于stack exchange,提问作者user24503

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 17:23:24