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