您的位置:首页 > 其它

Castle IOC容器实践之TypedFactory Facility(二)

2009-04-17 16:43 453 查看
摘要:在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类,这个类是一个空类,没有任何实现:


public class Empty






{




}
在实例化ComponentModel时需要传入的几个参数是:


public ComponentModel(String name, Type service, Type implementation)






{


this.name = name;




this.service = service;




this.implementation = implementation;




this.lifestyleType = LifestyleType.Undefined;




}
即这里用一个空的类型来代替实现了的类型。

上篇:Castle IOC容器实践之TypedFactory Facility(一)

参考资料

Castle的官方网站http://www.castleproject.org
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: