EasyNetQ由独立组件组成。 它在内部使用称为DefaultServiceProvider的小型内部DI(IoC)容器。 若是您查看用于建立核心IBus接口实例的静态RabbitHutch类的代码,您将看到它仅建立一个新的DefaultServiceProvider,注册全部EasyNetQ组件,而后调用container.Resolve()建立一个 IBus的新实例及其由容器提供的依赖关系树:git
public static IBus CreateBus(IConnectionConfiguration connectionConfiguration, Action<IServiceRegister> registerServices) { Preconditions.CheckNotNull(connectionConfiguration, "connectionConfiguration"); Preconditions.CheckNotNull(registerServices, "registerServices"); var container = createContainerInternal(); if (container == null) { throw new EasyNetQException("Could not create container. " + "Have you called SetContainerFactory(...) with a function that returns null?"); } registerServices(container); container.Register(_ => connectionConfiguration); ComponentRegistration.RegisterServices(container); return container.Resolve<IBus>(); }
可是若是你想让EasyNetQ使用你选择的容器呢? 从版本0.25开始,RabbitHutch类提供了一个静态方法SetContainerFactory,它容许您注册一个替代的容器工厂方法,该方法提供您所关心的EasyNetQ.IContainer的任何实现。github
Jeff Doolittle在这里为Windsor和Structure Map建立了容器包装:https://github.com/jeffdoolittle/EasyNetQ.DIapp
在这个例子中,咱们使用Castle Windsor IoC容器:ide
//注册咱们的替代容器工厂 RabbitHutch.SetContainerFactory(() => { //建立一个Windsor的实例 var windsorContainer = new WindsorContainer(); //将它包装在EasyNetQ.IContainer的实现中 return new WindsorContainerWrapper(windsorContainer); }); // 如今咱们能够建立一个IBus实例,但它是从windsor解决的,而不是EasyNetQ的默认服务提供者。 var bus = RabbitHutch.CreateBus("host=localhost");
这里是WindsorContainerWrapper:this
public class WindsorContainerWrapper : IContainer, IDisposable { private readonly IWindsorContainer windsorContainer; public WindsorContainerWrapper(IWindsorContainer windsorContainer) { this.windsorContainer = windsorContainer; } public TService Resolve<TService>() where TService : class { return windsorContainer.Resolve<TService>(); } public IServiceRegister Register<TService>(System.Func<IServiceProvider, TService> serviceCreator) where TService : class { windsorContainer.Register( Component.For<TService>().UsingFactoryMethod(() => serviceCreator(this)).LifeStyle.Singleton ); return this; } public IServiceRegister Register<TService, TImplementation>() where TService : class where TImplementation : class, TService { windsorContainer.Register( Component.For<TService>().ImplementedBy<TImplementation>().LifeStyle.Singleton ); return this; } public void Dispose() { windsorContainer.Dispose(); } }
请注意,全部EasyNetQ服务都应注册为singletons。spa
正确处理Windsor是很是重要的。 EasyNetQ不会在IContainer上提供Dispose方法,但您能够经过高级总线访问容器(是的,这也是新的),并以这种方式处置windsor:code
((WindsorContainerWrapper)bus.Advanced.Container).Dispose();
bus.Dispose();