主要内容

  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

  三.注册组件流程

  现在我们来看一下当注册一个组件时,容器做了什么?

双击代码全选
1
2
3
4
5
6
7
8
9
10
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);
}

  可以看到,WindsorContainer仅仅是调用了MicroKernel的方法来完成组件的注册,它只是对MicroKernel做了一次封装,核心的功能都由MicroKernel来完成,看一下MicroKernel中的AddComponent()方法的实现

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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);
}

  先做一些必要的异常处理,然后为当前组件创建ComponentModel实例,ComponentModel获取当前组件的详细元信息,而且这个信息在容器中的任何地方都可以使用,所以ComponentModel其实就是组件的一个“元信息库”。创建ComponentModel的过程如下:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
}

创建ComponentModel的过程其实就是调用contributor来对组件进行处理,它会按照顺序对添加进来的contributor依次调用,在DefaultComponentModelBuilder一共注册了八个Contributor,分别为:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
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() );
}

  这八个Contributor形成了一个处理组件的流程,它们涵盖了组件处理流程中的配置,生命周期,构造函数依赖,属性依赖等方面,每一个Contributor只负责某一方面的事情。再下来一步就是发出ComponentModelCreated事件了,这步的操作很简单

双击代码全选
1
2
3
4
5
6
protected virtual void RaiseComponentModelCreated(ComponentModel model)
{
  ComponentModelDelegate eventDelegate = (ComponentModelDelegate) events[ComponentModelCreatedEvent];
  if (eventDelegate != null) eventDelegate(model);
}

  现在ComponentModel创建完成,该是创建IHandler了,IHandler并不做创建组件的工作,它主要的功能是创建ComponentActivator,而ComponentActivator则是完成容器的组件创建工作,它首先会根据ComponentModel“信息库”检查相关的依赖,检查通过后根据生命周期管理来创建不同类型的组件,创建DefaultHandler的代码如下:

双击代码全选
1
2
3
4
5
6
7
public virtual IHandler Create(ComponentModel model)
{
  IHandler handler = new DefaultHandler(model);
  handler.Init(kernel);
  return handler;
}

Castle IOC容器内幕故事(上)的更多相关文章

  1. Castle IOC容器内幕故事(下)

    主要内容 1.ComponentModelBuilder 和 Contributors 2.Contributors分析 3.Handles分析 4.ComponentActivator分析 一.Co ...

  2. Castle IOC容器组件生命周期管理

    主要内容 1.生命处理方式 2.自定义生命处理方式 3.生命周期处理 一.生命处理方式 我们通常创建一个组件的实例使用new关键字,这样每次创建出来的都是一个新的实例,如果想要组件只有一个实例,我们会 ...

  3. Castle IOC容器与Spring.NET配置之比较

    我本人对于Spring.NET并不了解,本文只是通过一个简单的例子来比较一下两者配置之间的区别.在Castle IOC容器中,提出了自动装配(Auto-Wiring)的概念,即由容器自动管理组件之间的 ...

  4. Castle IOC容器快速入门

    主要内容 1.为什么要IOC 2.什么是Castle IOC容器 3.快速入门示例 4.几个重要的概念 一,为什么要IOC IOC(控制反转或者叫依赖注入)Martin Fowler大师在他的文章中已 ...

  5. Castle IOC容器构建配置详解(二)

    主要内容 1.基本类型配置 2.Array类型配置 3.List类型配置 4.Dictionary类型配置 5.自定义类型转换 一.基本类型配置 在Castle IOC的配置文件中,大家可能都已经注意 ...

  6. Castle IOC容器构建配置详解(一)

    主要内容 1.配置什么 2.几种配置方式 3.Include 介绍 4.Properties介绍 5.条件状态 一.配置什么 Castle IOC中并不像Spring.net那样贯穿着一个思想就是一切 ...

  7. Castle IOC容器实践之FactorySupport Facility

    PDF版本下载:http://file.ddvip.com/2008_10/1223538519_ddvip_4853.rar示例代码下载:http://file.ddvip.com/2008_10/ ...

  8. Spring IoC容器与应用上下文的设计与实现

    一.前言 写这篇博文的主要目的如下: 通过相关类和接口分析IoC容器到底长什么样. 阐述笔者对Spring上下文和容器的理解. 介绍重要的类辅助理解SpringBoot的启动流程. 二.Spring ...

  9. 【最简单IOC容器实现】实现一个最简单的IOC容器

    前面DebugLZQ的两篇博文: 浅谈IOC--说清楚IOC是什么 IoC Container Benchmark - Performance comparison 在浅谈IOC--说清楚IOC是什么 ...

随机推荐

  1. python numpy array 的一些问题

    1 将list转换成array 如果list的嵌套数组是不规整的,如 a = [[1,2], [3,4,5]] 则a = numpy.array(a)之后 a的type是ndarray,但是a中得元素 ...

  2. android 相对布局

    RelativeLayout布局 android:layout_marginTop="25dip" //顶部距离 android:gravity="left" ...

  3. trunc的使用

    1.日期比较时精确到日,可以使用 TRUNC(sysdate,'dd')函数.函数支持格式有:yyyy MM  dd  hh Mi可以用 select TRUNC(sysdate,'yyyy') fr ...

  4. Java中String为什么是final

    final概念: 如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父亲被继承.因此,一个类不能既被声明为abstract,又被声明为final. 将变量或方法声明为final,可以 ...

  5. cscope 的使用

    一. cscope安装 1.软件下载:http://sourceforge.net/project/showfiles.php?group_id=4664 2.软件安装: ./configure -- ...

  6. 史上最完整的Android开发工具集合

    路径: http://www.apkbus.com/thread-252748-1-1.html

  7. RIA+REST架构实现完美WEB开发

    记得第一次看到REST的身影,是在InfoQ上的一篇介绍,随后又翻阅了后面的参考文章和Developerwork上一些资料,甚至随手翻了翻Roy博士的论文.所幸,在不少人还在体会REST到底是何方神圣 ...

  8. nested push animation can result in corrupted navigation bar

    2013-12-06 10:15:51.668 CodingForFun[4569:70b] nested push animation can result in corrupted navigat ...

  9. linearlayout 水平垂直居中

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...

  10. 嵌入式 RTSP流媒体播放器实现

    最近需要做一个RTSP流媒体播放器,研究了一下,封装了一个RTSP播放类CRTSPPlayer,解码库采用ffmpeg.由于需求比较简单,时间也有限,目前只实现了播放.停止.暂停几个基本的接口.下面是 ...