初始化后配置MassTransit的Ninject绑定

时间:2015-04-08 13:59:54

标签: c# ninject masstransit

我想在我的代码中的某一点配置MassTransit(使用WebActivator)并在另一个配置消息处理程序(Ninject模块)。有没有办法实现这个目标?文档here显示了如何在一个步骤中执行我需要的操作,但是为了执行任何其他操作,看起来我需要获取ServiceBusConfigurator的实例,这似乎不是可从先前存在的IServiceBus

中获取

1 个答案:

答案 0 :(得分:0)

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

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

提示:您应该将以下代码片段视为伪代码,因为我已经从内存中写入了这些代码片段。它很可能不会编译

元数据模型

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)
        });
    }
});

基于公约的消费者绑定

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