Masstransit配置通用消费者

时间:2020-05-19 11:31:06

标签: c# dependency-injection masstransit

我正在使用MassTransit将消息传递代理集成到我们现有的应用程序中。 我们已经实现了一种具有通用实现的命令处理程序,如下所示:

public class MyCommandHandler: CommandHandlerBase<MyCommand>

现在,使通用的Consumer进行一些锅炉电镀并将工作交给DI容器的请求命令处理程序相对容易了。

public class CommandConsumer<TCommand> : IConsumer<TCommand>

然后我可以轻松地通过Microsoft DI进行注册:

cfg.AddConsumer<CommandConsumer<MyCommand>>(x => some configuration...);

这一切都很好,所以我继续下一步,即将消费者注册提取到一个通用的辅助方法中,这让我有些困惑。该方法(当前)看起来像这样

public static IServiceCollection ConfigureMassTransit(this IServiceCollection services, params Type[] consumerTypes)
{
        return 
            services.AddMassTransit(cfg =>
            {
                foreach (var consumerType in consumerTypes)
                {
                    cfg.AddConsumer(consumerType);
                }
                // or cfg.AddConsumers(consumerTypes);
                cfg.AddBus(context => Bus.Factory.CreateUsingRabbitMq(config =>
                {
                    var host = config.Host("localhost", "/",
                        h =>
                        {
                            h.Username("guest");
                            h.Password("guest");
                        });
                    config.ConfigureEndpoints(context);
                }));

            });
    }

,将其称为services.ConfigureMassTransit(typeof(CommandConsumer<MyCommand>)); 这再次有效,但是我不知道如何在注册中添加其他配置。仅当使用通用签名时,执行Action的重载才可用;只有Type可用时,才可以直接使用它。我尝试将标记类CommandConsumer: IConsumer添加到CommandConsumer<TCommand>并制作CommandConsumerDefinition : ConsumerDefinition<CommandConsumer>,然后将上面的内容更改为cfg.AddConsumer(consumerType, typeof(CommandConsumerDefinition));,但这没用,因为从没碰到ConfigureConsumer覆盖

我应该如何在编译时不知道其类型的使用者上添加其他配置?

1 个答案:

答案 0 :(得分:0)

Chris的回答使我走上了可行的解决方案之路。使CommandConsumerDefinition泛型使我可以在运行时使用反射以相同的方式构造这两种类型。这使MassTransit能够按预期方式连接配置。

最后,我还使用了“标记”属性来保存命令协定的类型,因此可以发现它们,而不必在启动时将其作为参数输入。

ErrorResponse

由于自动发现,我们已经处在反思领域,因此这似乎是可以接受的解决方案。这样,我们可以拥有通用的使用者和定义,而不必为我们拥有的每个命令协定添加新的类。