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 结合使用。如果你愿意,我可以发布一个例子。