摘要:在Castle IOC容器实践之TypedFactory Facility(一)里面大家都已经知道了如何去使用TypedFactory Facility,也已经体会到它的方便之处了,为了更好的使用它,本篇我们对TypedFactory Facility的原理做一些简单的分析。 TypedFactory Facility 原理分析 在TypedFactory Facility中,有一个 FactoryEntry 类,这个类与我们平时项目开发中的实体类有一些类似,它用来记录工厂的相关信息,包括工厂的ID,工厂的接口,创建方法和销毁方法。这个类实现如下: public class FactoryEntry { private String _id; private Type _factoryInterface; private String _creationMethod; private String _destructionMethod; public FactoryEntry(String id, Type factoryInterface, String creationMethod, String destructionMethod) { // 省略了验证及异常处理 _id = id; _factoryInterface = factoryInterface; _creationMethod = creationMethod; _destructionMethod = destructionMethod; } public String Id { get { return _id; } } public Type FactoryInterface { get { return _factoryInterface; } } public String CreationMethod { get { return _creationMethod; } } public String DestructionMethod { get { return _destructionMethod; } }} TypedFactoryFacility 同样是继承于AbstractFacility,关于Facility的继承关系我在前面的文章中已经说过了。TypedFactory Facility在初始化的时候首先会获取工厂的类型,通过SubSystem来得到: protected override void Init() { Kernel.AddComponent( "typed.fac.interceptor", typeof(FactoryInterceptor) ); ITypeConverter converter = (ITypeConverter) Kernel.GetSubSystem( SubSystemConstants.ConversionManagerKey ); AddFactories(FacilityConfig, converter);} protected virtual void AddFactories(IConfiguration facilityConfig, ITypeConverter converter) { if (facilityConfig != null) { foreach(IConfiguration config in facilityConfig.Children["factories"].Children) { String id = config.Attributes["id"]; String creation = config.Attributes["creation"]; String destruction = config.Attributes["destruction"]; Type factoryType = (Type) converter.PerformConversion( config.Attributes["interface"], typeof(Type) ); try { AddTypedFactoryEntry( new FactoryEntry(id, factoryType, creation, destruction) ); } catch(Exception ex) { throw new ConfigurationException("Invalid factory entry in configuration", ex); } } }} 然后再创建一个 FactoryEntry实例,记录了工厂的信息,放在了 ComponentModel的扩展属性 ExtendedProperties中,设置 ComponentModel的生命周期为 Singleton:
public void AddTypedFactoryEntry( FactoryEntry entry ) { ComponentModel model = new ComponentModel(entry.Id, entry.FactoryInterface, typeof(Empty)); model.LifestyleType = LifestyleType.Singleton; model.ExtendedProperties["typed.fac.entry"] = entry; model.Interceptors.Add( new InterceptorReference( typeof(FactoryInterceptor) ) ); Kernel.AddCustomComponent( model );} 在容器中加入一个工厂接口的拦截器
FactoryInterceptor ,当从容器中获取工厂时,会被拦截器拦截,拦截器的实现如下: [Transient] public class FactoryInterceptor : IMethodInterceptor, IOnBehalfAware { private FactoryEntry _entry; private IKernel _kernel; public FactoryInterceptor(IKernel kernel) { _kernel = kernel; } public void SetInterceptedComponentModel(ComponentModel target) { _entry = (FactoryEntry) target.ExtendedProperties["typed.fac.entry"]; } public object Intercept(IMethodInvocation invocation, params object[] args) { String name = invocation.Method.Name; if (name.Equals(_entry.CreationMethod)) { if (args.Length == 0 || args[0] == null) { return _kernel[ invocation.Method.ReturnType ]; } else { return _kernel[ (String) args[0] ]; } } else if (name.Equals(_entry.DestructionMethod)) { if (args.Length == 1) { _kernel.ReleaseComponent( args[0] ); return null; } } return invocation.Proceed(args); }} 还有一点需要我们注意的是在上面实例化 ComponentModel的时候用到了一个 Empty类,这个类是一个空类,没有任何实现:
在实例化 ComponentModel时需要传入的几个参数是:
public ComponentModel(String name, Type service, Type implementation) { this.name = name; this.service = service; this.implementation = implementation; this.lifestyleType = LifestyleType.Undefined;} 本文转自lihuijun51CTO博客,原文链接:http://blog.51cto.com/terrylee/67689 ,如需转载请自行联系原作者