public class FactoryEntry
{
private string _id, _creationMethod, _destructionMethod;
private Type _factoryInterface;
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; } }
}
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));
AddTypedFactoryEntry(new FactoryEntry(id, factoryType, creation, destruction));
}
}
}
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);
}
Empty 為空類別,僅佔位:
public class Empty { }
[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);
}
}
攔截 Create 方法:無參數則按回傳型別解析,有參數則按 Key 解析;攔截 Release 方法釋放組件。至此 TypedFactory Facility 運作原理完全透明。