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


posted @ 2012-10-18 11:42  alby  阅读(2295)  评论(1编辑  收藏  举报