2014-11-04 101 views
4

我试图使用EasyNetQ和Ninject来记录消息。我设法将Ninject设置为EasyNetQ DI(我认为),但是当一个消息到达一个没有无参数构造函数的处理程序(例如,我需要一个在那里绑定的存储库)时,它不能解析。或者至少我相信这是问题,因为我在控制台上遇到了一个非常普遍的错误。在EasyNetQ/RabbitMQ消息处理程序中使用Ninject

我告诉EasyNetQ使用Ninject像这样:

RabbitHutch.SetContainerFactory(() => new NinjectAdapter(container)); 

我觉得这是我需要来进行设置。 Ninject适配器是EasyNetQ的一个。

我的处理程序如下所示:

public class ProfileDeactivatedUpdateHandler : IConsume<ProfileDeactivatedUpdate> 
{ 
    private readonly IProfileRepository _profileRepository; 

    public ProfileDeactivatedUpdateHandler(IProfileRepository profileRepository) 
    { 
     _profileRepository = profileRepository; 
    } 

    public void Consume(ProfileDeactivatedUpdate message) 
    { 
     //Do Stuff. 
    } 
} 

如果我添加一个参数的构造函数,而是设置Ninject是可以通过服务定位器(唉),那么它的工作原理。处理程序调用的很好,我可以通过ServiceLocator找到我的存储库,所以我知道至少Ninject知道存储库。

当它试图处理消息时弹出的错误是。

System.AggregateException: One or more errors occurred. ---> System.Exception: E 
xception of type 'System.Exception' was thrown. 
    at EasyNetQ.ReflectionHelpers.DefaultFactories`1.Get() 
    at EasyNetQ.ReflectionHelpers.CreateInstance[T]() 
    at EasyNetQ.AutoSubscribe.DefaultAutoSubscriberMessageDispatcher.Dispatch[TMe 
ssage,TConsumer](TMessage message) 
    at EasyNetQ.RabbitBus.<>c__DisplayClass6`1.<Subscribe>b__5(T msg) 
    --- End of inner exception stack trace --- 
---> (Inner Exception #0) System.Exception: Exception of type 'System.Exception' 
was thrown. 
    at EasyNetQ.ReflectionHelpers.DefaultFactories`1.Get() 
    at EasyNetQ.ReflectionHelpers.CreateInstance[T]() 
    at EasyNetQ.AutoSubscribe.DefaultAutoSubscriberMessageDispatcher.Dispatch[TMe 
ssage,TConsumer](TMessage message) 
    at EasyNetQ.RabbitBus.<>c__DisplayClass6`1.<Subscribe>b__5(T msg)<--- 

回答

4

所以我已经解决了这个问题。显然,当EasyNetQ实例化一个处理程序时,它并不使用指定的DI框架来执行它(Boo!)。你必须单独指定一个“MessageDispatcher”实现。真棒!哦......但是......只有Autofac的实现,而不是Ninject(Boo!x2)。

所以,我拉的要求是这里的代码来实现对Ninject事件调度是在这里: https://github.com/mikehadlow/EasyNetQ/pull/309

现在,你可以在类复制并粘贴到您的项目。然后在你的NinjectModule或任何你正在设置您的绑定,您可以执行以下操作:

//Bind Message Dispatcher to Ninject event message dispatcher 
NinjectMessageDispatcher messageDispatcher = new NinjectMessageDispatcher(Kernel); 
Bind<IAutoSubscriberMessageDispatcher>().ToConstant(messageDispatcher); 

那么无论你设置你的用户,你可以做类似如下(请注意,这使用的自动订阅EasyNetQ的IConsume接口。

var subscriber = new AutoSubscriber(_serviceBus, "ProfileServices"); 
subscriber.AutoSubscriberMessageDispatcher = _dispatcher; 
subscriber.Subscribe(Assembly.GetExecutingAssembly()); 

的重要组成部分,是MessageDispatcher设置手动到ninject调度员的一个实例。你想怎么做到这一点是由你。

我认为,在未来, EasyNetQ p可以自动执行此操作。显然,如果您将工厂设置为使用Ninject,则您的处理程序可能也希望使用Ninject。

哦!你可以修改上面的代码来使用你选择的DI。这需要完成任何使用EasyNetQ的DI(我认为),而不仅仅是Ninject。

+0

感谢您回来回答这个问题。合并请求! – 2014-11-07 21:44:56

相关问题