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

Castle IOC容器內幕故事(下)

編輯:關於.NET

主要內容

1.ComponentModelBuilder 和 Contributors

2.Contributors分析

3.Handles分析

4.ComponentActivator分析

一.ComponentModelBuilder 和 Contributors

在前一篇中介紹組件的注冊流程時說到了,創建ComponentModel的過程就是調用contributor來對組件進行處理的過程。Contributor就是我們這個內幕故事的第一個主角,在DefaultComponentModelBuilder一共注冊了八個Contributor,每一個Contributor都專門負責處理某一方面的事情。如下代碼所示:

protected virtual void InitializeContributors()
{
  AddContributor( new ConfigurationModelInspector() );
  AddContributor( new LifestyleModelInspector() );
  AddContributor( new ConstructorDependenciesModelInspector() );
  AddContributor( new PropertiesDependenciesModelInspector() );
  AddContributor( new MethodMetaInspector() );
  AddContributor( new LifecycleModelInspector() );
  AddContributor( new ConfigurationParametersInspector() );
  AddContributor( new InterceptorInspector() );
}
// http://terrylee.cnblogs.com

1.ConfigurationModelInspector:用來處理配置,它使用ConfigurationStore在Kernel中注冊來保持一個組件的連接。

2.LifestyleModelInspector:生命周期處理方式,主要有Singleton、Thread、Transient、Pooled、Custom這些都可以在配置文件中指定,後續文章會講到。

3.ConstructorDependenciesModelInspector:處理構造函數依賴,收集所有的Public構造函數,並它們交給ComponentModel的Constructors集合。

4.PropertiesDependenciesModelInspector:處理屬性依賴,收集所有的可寫的屬性,Kernel也許不會在組件注冊時就設置所有的屬性,也有可能在請求獲取組件時來設置。

5.MethodMetaInspector:檢測組件配置中的Method節點,每一個節點都將添加到ComponentModel的Method集合中。

6.LifecycleModelInspector:處理組件生命周期,即在組件裝載,初始化,銷毀所出發的行為,分別對應三個接口:IInitializable,ISupportInitialize,IDisposable,如果組件實現了這些接口,容器會自動在不同的生命周期調用它們。

7.ConfigurationParametersInspector:處理配置文件中的parameters元素內容,每一個parameters都將創建一個ParameterModel,並添加到ComponentModel的Parameters集合中。

8.InterceptorInspector:處理InterceptorAttribute或者配置文件中的interceptors元素的信息。

在有些情況下,我們可能並不需要這麼多的Contributors,或者說我們想添加自定義的Contributors,可以用ComponentModelBuilder的如下兩個方法來實現對Contributors的管理:

public void AddContributor(IContributeComponentModelConstruction contributor)
{
  contributors.Add(contributor);
}
public void RemoveContributor(IContributeComponentModelConstruction contributor)
{
  contributors.Remove(contributor);
}
// http://terrylee.cnblogs.com

二.Contributors分析

通過上面的分析可以看到八個Contributors按一定順序組合構成了整個組件的處理流程,現在我們來看一下Contributors是如何實現的?每一個Contributors都必須實現於接口IcontributeComponentModelConstruction,通過這個,我們可以創建自己的Contributors:

public interface IContributeComponentModelConstruction
{
  void ProcessModel(IKernel kernel, ComponentModel model);
}
// http://terrylee.cnblogs.com

來看一下其中LifecycleModelInspector的實現代碼:

[Serializable]
public class LifecycleModelInspector : IContributeComponentModelConstruction
{
  public LifecycleModelInspector()
  {
  }
  public virtual void ProcessModel(IKernel kernel, ComponentModel model)
  {
    if (typeof (IInitializable).IsAssignableFrom(model.Implementation))
    {
      model.LifecycleSteps.Add( LifecycleStepType.Commission, InitializationConcern.Instance );
    }
    if (typeof (ISupportInitialize).IsAssignableFrom(model.Implementation))
    {
      model.LifecycleSteps.Add( LifecycleStepType.Commission, SupportInitializeConcern.Instance );
    }
    if (typeof (IDisposable).IsAssignableFrom(model.Implementation))
    {
      model.LifecycleSteps.Add( LifecycleStepType.Decommission, DisposalConcern.Instance );
    }
  }
}
// http://terrylee.cnblogs.com

至此,第一個主角Contributors的故事就完了。

三.Handles分析

在組件注冊流程中,還提到了一個重要的角色就是Handles。對Handles的描述引用Castle官方網站的一句話來說就是“They don't construct the component themselves, but they know who does”。Handles它有兩個狀態,分別標識組件是否可以被請求還是需要繼續等待相關的依賴,所有的Handles都必須實現IHandles接口,通過這個也可以創建自己的Handle。

public enum HandlerState
{
  Valid,
  WaitingDependency
}
public interface IHandler
{
  void Init(IKernel kernel);
  object Resolve();
  void Release(object instance);
  HandlerState CurrentState { get; }
  ComponentModel ComponentModel { get; }
}
// http://terrylee.cnblogs.com

Handles通過下面兩個方法來檢查哪些組件可以被請求,而哪些組件需要繼續等待相關依賴,但是它並不做具體的組件創建工作。

public override object Resolve()
{
  if (CurrentState == HandlerState.WaitingDependency)
  {
    String message =
      String.Format("Can't create component '{1}' as it has dependencies to be satisfied. {0}",
        ObtainDependencyDetails(), ComponentModel.Name );
    throw new HandlerException(message);
  } 
  return lifestyleManager.Resolve();
}
public override void Release(object instance)
{
  lifestyleManager.Release( instance );
}
// http://terrylee.cnblogs.com

四.ComponentActivator分析

介紹完前面三位角色之後,今天最後一位登場的主角就是ComponentActivator,組件激活器。每一個組件都和一個Activator相關聯。Castle IOC為我們提供了默認的Activator,Castle IOC已經為我們提供了默認的Activator,但有時候也需要自己去實現Activator,比如說創建組件的實例並不是new出來的,而是通過我們自定義的Factory方法創建的,或者說我們需要創建的組件一個Remoting組件。創建自定義的Activator需要繼承於AbstractComponentActivator基類或者DefaultComponentActivator。

[Serializable]
public abstract class AbstractComponentActivator : IComponentActivator
{
  private IKernel kernel;
  private ComponentModel model;
  private ComponentInstanceDelegate onCreation;
  private ComponentInstanceDelegate onDestruction;
  public AbstractComponentActivator(ComponentModel model, IKernel kernel,
    ComponentInstanceDelegate onCreation,
    ComponentInstanceDelegate onDestruction)
  {
    this.model = model;
    this.kernel = kernel;
    this.onCreation = onCreation;
    this.onDestruction = onDestruction;
  }
  public IKernel Kernel
  {
    get { return kernel; }
  }
  public ComponentModel Model
  {
    get { return model; }
  }
  public ComponentInstanceDelegate OnCreation
  {
    get { return onCreation; }
  }
  public ComponentInstanceDelegate OnDestruction
  {
    get { return onDestruction; }
  }
  protected abstract object InternalCreate();
  protected abstract void InternalDestroy(object instance);
  IComponentActivator Members#region IComponentActivator Members
  public virtual object Create()
  {
    object instance = InternalCreate();
    onCreation(model, instance);
    return instance;
  }
  public virtual void Destroy(object instance)
  {
    InternalDestroy(instance);
    onDestruction(model, instance);
  }
  #endregion
}
// http://terrylee.cnblogs.com

關於Castle IOC內部主角分析就到這裡了,至此Castle IOC的內幕故事也告一段落了,通過這兩篇文章我們對Castle IOC的內幕有了一個簡單的認識,這對於我們使用Castle IOC有很大的好處,後續文章會講到。

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