主要內容
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 )
在容器中加入一個工廠接口的攔截器FactoryInterceptor,當從容器中獲取工廠時,會被攔截器攔截,攔截器的實現如下:
{
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 );
}
[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;
}
即這裡用一個空的類型來代替實現了的類型。