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

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

編輯:關於.NET

主要內容

Startable Facility原理分析

……

在Castle IOC容器實踐之Startable Facility(一)中我們已經看到了如何去使用Startable Facility,本文將對它的原理做一些分析。先看一下接口IStartable,它的實現代碼如下:

public interface IStartable
{
  void Start();
  void Stop();
}

代碼是相當的簡單,只有兩個方法,分別在組件創建的時候和銷毀的時候執行,這就涉及到了組件的生命周期管理。在Windsor中,接口ILifecycleConcern提供特定的組件生命周期管理:

public interface ILifecycleConcern
{
  void Apply( ComponentModel model, object component );
}

現在我們要實現組件的自動創建和銷毀,就需要實現接口ILifecycleConcern,在Startable Facility中分別用兩個類來實現,第一個類StartConcern,它判斷如果組件實現了接口IStartable,則直接調用它的Start()方法;如果組件是用特性startMethod,則獲取並調用具有startMethod特性的方法:
public class StartConcern : ILifecycleConcern
{
  private static readonly StartConcern _instance = new StartConcern();
  protected StartConcern()
  {
  }
  public static StartConcern Instance
  {
    get { return _instance; }
  }
  public void Apply(ComponentModel model, object component)
  {
    if (component is IStartable)
    {
      (component as IStartable).Start();
    }
    else if (model.Configuration != null)
    {
      String startMethod = model.Configuration.Attributes["startMethod"];
      if (startMethod != null)
      {
        MethodInfo method = model.Implementation.GetMethod(startMethod);
        method.Invoke(component, null);
      }
    }
  }
}

第二個類是StopConcern,它判斷如果組件實現了接口IStartable,則直接調用它的Stop()方法;如果組件是用特性stopMethod,則獲取並調用具有stopMethod特性的方法:

public class StopConcern : ILifecycleConcern
{
  private static readonly StopConcern _instance = new StopConcern();
  protected StopConcern()
  {
  }
  public static StopConcern Instance
  {
    get { return _instance; }
  }
  public void Apply(ComponentModel model, object component)
  {
    if(component is IStartable)
    {
      (component as IStartable).Stop();
    }
    else if (model.Configuration != null)
    {
      String stopMethod = model.Configuration.Attributes["stopMethod"];
      if (stopMethod != null)
      {
        MethodInfo method = model.Implementation.GetMethod(stopMethod);
        method.Invoke(component, null);
      }
    }
  }
}

好了,知道了Startable Facility如何管理組件的生命周期,我們就來看看真正的Startable Facility是如何實現的。每一個Facility都是滿足這樣的一個繼承關系:

圖1 Facility繼承關系圖

其中的Abstract Facility提供了一些默認的實現,Facility可以直接實現IFacility,也可以繼承於Abstract Facility。IFacility的實現如下:

public interface IFacility
{
  void Init(IKernel kernel, IConfiguration facilityConfig);
  void Terminate();
}

那麼到底如何讓組件滿足依賴性後就自動執行呢?注意到再Startable Facility的Init()注冊了這樣的兩個事件:

protected override void Init()
{
  converter = (ITypeConverter) Kernel.GetSubSystem(SubSystemConstants.ConversionManagerKey);
  Kernel.ComponentModelCreated +=
    new ComponentModelDelegate(OnComponentModelCreated);
  Kernel.ComponentRegistered +=
    new ComponentDataDelegate(OnComponentRegistered);
}

分別為OnComponentModelCreated和OnComponentRegistered。當我們注冊一個組件時首先會出發OnComponentRegistered事件,在它裡面判斷組件是否滿足依賴性,如果不滿足,則添加到一個等待列表中,否則就直接啟動,然後再對這個等待列表進行檢測,看添加改組件後,列表中是否有組件滿足了依賴性:

private void OnComponentRegistered(String key, IHandler handler)
{
  bool startable = (bool) handler.ComponentModel.ExtendedProperties["startable"];
  if (startable)
  {
    if (handler.CurrentState == HandlerState.WaitingDependency)
    {
      waitList.Add( handler );
    }
    else
    {
      Start( key );
    }
  }
  CheckWaitingList();
}
private void CheckWaitingList()
{
  IHandler[] handlers = (IHandler[]) waitList.ToArray( typeof(IHandler) );
  IList validList = new ArrayList();
  foreach(IHandler handler in handlers)
  {
    if (handler.CurrentState == HandlerState.Valid)
    {
      validList.Add(handler);
      waitList.Remove(handler);
    }
  }
  foreach(IHandler handler in validList)
  {
    Start( handler.ComponentModel.Name );
  }
}

剛才說到,如果滿足了依賴性,則會請求創建這個組件:

private void Start(String key)
{
  object instance = Kernel[key];
}

這時就觸發了OnComponentModelCreated事件,這時就該用到開始我們所講的那兩生命周期處理的類了:

private void OnComponentModelCreated(ComponentModel model)
{
  bool startable =
    CheckIfComponentImplementsIStartable(model) || HasStartableAttributeSet(model);
  model.ExtendedProperties["startable"] = startable;
  if (startable)
  {
    model.LifecycleSteps.Add(
      LifecycleStepType.Commission, StartConcern.Instance );
    model.LifecycleSteps.Add(
      LifecycleStepType.Decommission, StopConcern.Instance );
  }
}

首先還是先判斷組件是否實現了IStartable接口或這時候有特性startable,如果沒有那也就不用自動啟動了,否則就把StartConcern和StopConcern分別注冊為組件的生命周期開始行為和生命周期結束行為,(關於組件的生命周期的詳細內容可以參考我前面寫的Castle IOC容器組件生命周期管理)。此時組件進入生命周期開始,會調用StartConcern的Apply()方法,這時就觸發組件的Start()方法,同樣在組件銷毀時調用StopConcern的Apply()方法,這時就會調用組件的Stop()方法。這樣就完成整個了組件的自動執行與銷毀的全過程。

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