zoukankan      html  css  js  c++  java
  • 18,EasyNetQ-使用替代DI容器

    EasyNetQ由独立组件组成。 它在内部使用称为DefaultServiceProvider的小型内部DI(IoC)容器。 如果您查看用于创建核心IBus接口实例的静态RabbitHutch类的代码,您将看到它仅创建一个新的DefaultServiceProvider,注册所有EasyNetQ组件,然后调用container.Resolve()创建一个 IBus的新实例及其由容器提供的依赖关系树:

    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的任何实现。

    Jeff Doolittle在这里为Windsor和Structure Map创建了容器包装:https://github.com/jeffdoolittle/EasyNetQ.DI

    在这个例子中,我们使用Castle Windsor IoC容器:

    //注册我们的替代容器工厂
    RabbitHutch.SetContainerFactory(() =>
        {
            //创建一个Windsor的实例
            var windsorContainer = new WindsorContainer();
    
            //将它包装在EasyNetQ.IContainer的实现中
            return new WindsorContainerWrapper(windsorContainer);
        });
    
    // 现在我们可以创建一个IBus实例,但它是从windsor解决的,而不是EasyNetQ的默认服务提供者。
    var bus = RabbitHutch.CreateBus("host=localhost");

    这里是WindsorContainerWrapper:

    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。

    正确处理Windsor是非常重要的。 EasyNetQ不会在IContainer上提供Dispose方法,但您可以通过高级总线访问容器(是的,这也是新的),并以这种方式处置windsor:

    ((WindsorContainerWrapper)bus.Advanced.Container).Dispose();
    bus.Dispose();
  • 相关阅读:
    配置Apache虚拟主机
    Apache: You don't have permission to access / on this server
    wordpress之备份与恢复数据
    ruby之各种概念
    Oracle之比较NVARCHAR2字符串
    Centos安装ruby--jekyll
    Linux之IO Redirection
    SecureCRT导入已有会话
    jdk1.8新特性应用之Iterable
    jdk1.8新特性应用之Collection
  • 原文地址:https://www.cnblogs.com/zd1994/p/8652564.html
Copyright © 2011-2022 走看看