请注意,本站并不支持低于IE8的浏览器,为了获得最佳效果,请下载最新的浏览器,推荐下载 Chrome浏览器
欢迎光临。交流群:166852192

Orchard源码分析(4.1):Orchard.Environment.CollectionOrderModule类


CollectionOrderModule类是一个Autofac模块(Module,将一系列组件和相关的功能包装在一起),而非Orchard模块。其作用是保证多个注册到容器的组件能按FIFO(First In First Out)的顺序提取。下面举例说明:

1、创建ICustomerService接口:

    public interface ICustomerService { }
  
2、创建两个实现ICustomerService接口的类:

    public class DefaultCustomerService : ICustomerService { }
    public class VIPCustomerService : ICustomerService { }
  
3、测试:
    [TestFixture]
    public class AutofacTest
    {
        [ Test]
        public void TestCollectionModule()
        {
            ContainerBuilder builder = new ContainerBuilder();
            //builder.RegisterModule(new CollectionOrderModule());
            builder.RegisterType< DefaultCustomerService>().As<ICustomerService >();
            builder.RegisterType< VIPCustomerService>().As<ICustomerService >();


            IContainer container = builder.Build();
            var customeres = container.Resolve<IEnumerable< ICustomerService>>();
            //判断第一个注册的服务,取出来是不是第一个
            Assert.That(customeres.First(), Is .TypeOf<DefaultCustomerService>());
            //判断最后一个注册的服务,取出来是不是最后一个
            Assert.That(customeres.Last(), Is .TypeOf<VIPCustomerService>());


            //只影响集合解析,解析单个Service不受影响
            var customer = container.Resolve<ICustomerService >();
            Assert.That(customer, Is .TypeOf<VIPCustomerService>());


        }
    }
上述代码是不能测试通过的。

4、如果向Autofac容器注册一个CollectionOrderModule,将能确保测试通过:

        [ Test]
        public void TestCollectionModule()
        {
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterModule( newCollectionOrderModule ());
            //...
        }
附,CollectionOrderModule的源码:
    class CollectionOrderModule IModule {
        public void Configure( IComponentRegistry componentRegistry) {
            componentRegistry.Registered += (sender, registered) => {
                // only bother watching enumerable resolves
                var limitType = registered.ComponentRegistration.Activator.LimitType;
                if (typeof ( IEnumerable).IsAssignableFrom(limitType)) {
                    registered.ComponentRegistration.Activated += (sender2, activated) => {
                        // Autofac's IEnumerable feature returns an Array
                        if (activated.Instance is Array) {
                            // Orchard needs FIFO, not FILO, component order
                            Array .Reverse((Array )activated.Instance);
                        }
                    };
                }
            };
        }
    }


Orchard这么做的目的有待于进一步发掘研究。但有一定可以肯定,Orchard对某些组件是顺序敏感的。

参考资料:
Autofac:Structuring With Modules
Autofac:Activation events

Autofac.Module

作者原创内容不容易,如果觉得内容不错,请点击右侧“打赏”,赏俩给作者花花,也算是对作者付出的肯定,也可以鼓励作者原创更多更好内容。
更多详情欢迎到QQ群 166852192 交流。