Orchard源码分析(4.1):Orchard.Environment.CollectionOrderModule类
CollectionOrderModule类是一个Autofac模块(Module,将一系列组件和相关的功能包装在一起),而非Orchard模块。其作用是保证多个注册到容器的组件能按FIFO(First In First Out)的顺序提取。下面举例说明:
1、创建ICustomerService接口:
2、创建两个实现ICustomerService接口的类:
3、测试:
1、创建ICustomerService接口:
public interface ICustomerService { }
public class DefaultCustomerService : ICustomerService { }
public class VIPCustomerService : ICustomerService { }
[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,将能确保测试通过:
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:Structuring With Modules Autofac:Activation events