首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Castle IOC 實踐:TypedFactory Facility(二)原理篇

     編輯:關於.NET

FactoryEntry:工廠元資料記錄


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; } }
}

Facility 初始化:解析配置建立 FactoryEntry


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 { }

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);
    }
}

攔截 Create 方法:無參數則按回傳型別解析,有參數則按 Key 解析;攔截 Release 方法釋放組件。至此 TypedFactory Facility 運作原理完全透明。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved