【问题标题】:Configuring MassTransit's Ninject bindings after initialisation初始化后配置 MassTransit 的 Ninject 绑定
【发布时间】:2015-04-08 13:59:53
【问题描述】:

我想在我的代码中的某个位置(使用 WebActivator)配置 MassTransit,并在另一个位置(一个 Ninject 模块)中配置消息处理程序。有没有办法可以做到这一点?文档here 展示了如何一步执行我需要的操作,但要执行其他操作,看起来我需要获取ServiceBusConfigurator 的实例,这似乎无法从现有的@987654323 获得@

【问题讨论】:

    标签: c# ninject masstransit


    【解决方案1】:

    IServiceBus 的配置和创建不能分开。 这意味着,您唯一的选择是在创建总线之前收集配置信息更多时间。

    正如doc you linked 所述,ninject 提供的元数据信息不足以创建订阅。这基本上意味着您必须创建自己的元数据模型。让我们举个例子,它可以用于单一注册,也可以用于基于约定的注册:

    提示:您应该将以下代码 sn-ps 视为伪代码,因为我是从内存中编写的。它很可能不会编译

    元数据模型

    public class SubscriptionMetadata
    {
        public SubscriptionMetadata(Type consumer)
        {
            if(!typeof(IConsumer).IsAssignableFrom(consumer))
            {
                string message = string.Format(
                    "{0} does not implement {1}",
                    typeof(IConsumer).Name,
                    consumer.Name);
                throw new ArgumentOutOfRangeException("consumer", message);
            }
    
            this.ConsumerType = consumer;
        }
    
        public Type ConsumerType { get; private set; }
    }
    

    元数据的注册

    现在可以在 Ninject 模块中像这样使用它:

    Bind<SubscriptionMetadata>()
       .ToConstant(new SubscriptionMetadata(typeof(FooConsumer));
    

    如果您要经常使用它,我建议您编写一个扩展方法:

    public static class SubscriptionBindingExtensions
    {
        public static void BindConsumer<T>(this IBindingRoot bindingRoot)
            where T : IConsumer
        {
            Bind<SubscriptionMetadata>()
              .ToConstant(new SubscriptionMetadata(typeof(T));
        }
    }
    

    和用法(@Module):

    BindConsumer<FooConsumer>();
    

    IServiceBus创作

    现在您将修改 IServiceBus 创建如下:

    var kernel = new StandardKernel();
    // 2nd Step left out: load all IModule`s ..
    
    var bus = ServiceBusFactory.New(sbc =>
    {
        //other configuration options
    
        foreach(var metadata in kernel.GetAll<SubscriptionMetadata>())
        {
            sbc.Subscribe(subs =>
            {
                subs.Consumer(metadata.ConsumerType, kernel)
            });
        }
    });
    

    基于约定的消费者绑定

    它还可以通过利用IBindingCreator 接口与conventions 结合使用。如果你愿意,我可以发布一个例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多