18,EasyNetQ-使用替代DI容器

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();
相关文章
相关标签/搜索