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

Castle IOC容器內幕故事(上)

編輯:關於.NET

主要內容

1.WindsorContainer分析

2.MicroKernel分析

3.注冊組件流程

一.WindsorContainer分析

WindsorContainer是Castle的IOC容器,也是它的一個核心,先來看一下WindsorContainer在Castle中所處的位置:

圖1

WindsorContainer構建於MicroKernel之上,MicroKernel僅僅是提供了一個IOC的容器,非常的輕巧,它只依賴於Castle.Model一個程序集,但它的可擴展能力卻很強,後面會講到;可以這麼理解,WindsorContainer為我們提供了一個Façade,它封裝了MicroKernel,並且提供了一些擴展點,但它的核心仍然是Microkernel。如下圖所示:

圖2

二.MicroKernel分析

既然MicroKernel是WindsorContainer的核心,那我們就來看一下MicroKernel的結構,從下面的結構圖中,可以看到MicroKernel的組成主要有SubSystem,Components,Facilities幾個部分,SubSystem主要用來處理一些擴展功能,如配置、類型轉換等,我們也可以實現自己的SubSystem;Components稱為組件,在快速入門指南中我已經提到了,這裡再說一下,服務是一個個的接口,接口約定了服務,從而使隨意替換服務的實現對使用接口服務的代碼沒有任何的影響,組件是一個可重用的程序單元,它實現了某個接口,並僅僅只實現了這一個良好的接口,也就是說,組件是實現了某個服務接口的類;Facilities我們稱之為擴張單元,如果我們想擴張容器的功能,可以通過創建擴張單元來實現,我們可以在擴張單元裡面訂閱容器事件,給組件附加屬性,建立攔截器,控制組件生命周期等,擴張單元是以一種插件的形式存在的,所以非常便於擴展,可以編寫自己的擴張單元,後面我會寫Castle自帶的一些擴張單元的使用。MicroKernel的結構如下圖:

圖3

三.注冊組件流程

現在我們來看一下當注冊一個組件時,容器做了什麼?

public virtual void AddComponent(String key, Type classType)
{
  _kernel.AddComponent(key, classType);
}

public virtual void AddComponent(String key, Type serviceType, Type classType)
{
  _kernel.AddComponent(key, serviceType, classType);
}
// http://terrylee.cnblogs.com

可以看到,WindsorContainer僅僅是調用了MicroKernel的方法來完成組件的注冊,它只是對MicroKernel做了一次封裝,核心的功能都由MicroKernel來完成,看一下MicroKernel中的AddComponent()方法的實現

public virtual void AddComponent(String key, Type classType)
{
  if (key == null) throw new ArgumentNullException("key");
  if (classType == null) throw new ArgumentNullException("classType");

  ComponentModel model = ComponentModelBuilder.BuildModel(key, classType, classType, null);
  RaiseComponentModelCreated(model);
  IHandler handler = HandlerFactory.Create(model);
  RegisterHandler(key, handler);
}

public virtual void AddComponent(String key, Type serviceType, Type classType)
{
  if (key == null) throw new ArgumentNullException("key");
  if (serviceType == null) throw new ArgumentNullException("serviceType");
  if (classType == null) throw new ArgumentNullException("classType");

  ComponentModel model = ComponentModelBuilder.BuildModel(key, serviceType, classType, null);
  RaiseComponentModelCreated(model);
  IHandler handler = HandlerFactory.Create(model);
  RegisterHandler(key, handler);
}
// http://terrylee.cnblogs.com

先做一些必要的異常處理,然後為當前組件創建ComponentModel實例,ComponentModel獲取當前組件的詳細元信息,而且這個信息在容器中的任何地方都可以使用,所以ComponentModel其實就是組件的一個“元信息庫”。創建ComponentModel的過程如下:

public ComponentModel BuildModel(String key, Type service,
  Type classType, IDictionary extendedProperties)
{
  ComponentModel model = new ComponentModel(key, service, classType);
  if (extendedProperties != null)
  {
    model.ExtendedProperties = extendedProperties;
  }
  foreach(IContributeComponentModelConstruction contributor in contributors)
  {
    contributor.ProcessModel( kernel, model );
  }
  return model;
}
// http://terrylee.cnblogs.com

創建ComponentModel的過程其實就是調用contributor來對組件進行處理,它會按照順序對添加進來的contributor依次調用,在DefaultComponentModelBuilder一共注冊了八個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

這八個Contributor形成了一個處理組件的流程,它們涵蓋了組件處理流程中的配置,生命周期,構造函數依賴,屬性依賴等方面,每一個Contributor只負責某一方面的事情。再下來一步就是發出ComponentModelCreated事件了,這步的操作很簡單

protected virtual void RaiseComponentModelCreated(ComponentModel model)
{
  ComponentModelDelegate eventDelegate = (ComponentModelDelegate) events[ComponentModelCreatedEvent];
  if (eventDelegate != null) eventDelegate(model);
}
// http://terrylee.cnblogs.com

現在ComponentModel創建完成,該是創建IHandler了,IHandler並不做創建組件的工作,它主要的功能是創建ComponentActivator,而ComponentActivator則是完成容器的組件創建工作,它首先會根據ComponentModel“信息庫”檢查相關的依賴,檢查通過後根據生命周期管理來創建不同類型的組件,創建DefaultHandler的代碼如下:

public virtual IHandler Create(ComponentModel model)
{
  IHandler handler = new DefaultHandler(model);
  handler.Init(kernel);
  return handler;
}
//http://terrylee.cnblogs.com

ComponentRegistered、HandlerRegistered事件,完成整個組件的注冊過程。

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