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