程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Castle IOC容器實踐之TypedFactory Facility(二)

Castle IOC容器實踐之TypedFactory Facility(二)

編輯:關於.NET

主要內容

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

即這裡用一個空的類型來代替實現了的類型。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved