主要内容

  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. yaf框架流程二

    这篇讲讲yaf的配置文件,首先上我的配置代码: [common] ;必选配置 ;application.directory String 应用的绝对目录路径 ;可选配置 ;名称 值类型 默认值 说明 ...

  2. [转] gc tips(1)

    所有应用软件都需要管理内存,一个应用软件的内存管理系统包括了如下准则:什么时候派发内存,要派发多少内存,什么时候把东西放到回收站,以及什么时候清空回收站.MMgc是Flash Player几乎所有内存 ...

  3. string tips

    1. .net文档中说,split 比 indexOf 消耗更多的性能.在as3中经过本人测试,这个结论一样成立.而且,字符串越长,split和indexOf的差距就越明显!!所以,能用indexOf ...

  4. Linux/Unix shell 监控Oracle告警日志(monitor alter log file)

    使用shell脚本实现对Oracle数据库的监控与管理将大大简化DBA的工作负担,如常见的对实例的监控,监听的监控,告警日志的监控,以及数据库的备份,AWR report的自动邮件等.本文给出Linu ...

  5. 常用应用层协议HTTP、RTSP、RTMP比较

    HTTP(超文本传输协议).RTSP(Real Time Streaming Protocol实时流传输协议).RTMP(Routing Table Maintenance Protocol路由选择表 ...

  6. uglifyjs使用

    1.安装Nodejs:去这里下载并安装. 2.打开cmd,运行npm,node应该会有输出东西 3.如果在window上运行Node.js的npm报Error: ENOENT, stat 'C:\Us ...

  7. 虚拟机VMware tools作用以及其安装

    虚拟机VMware tools的作用(1). 更新虚拟机中的显卡驱动, 使虚拟机中的XWindows可以运行在SVGA模式下.在客户操作系统中安装Mware Tools非常重要.如果不安装VMware ...

  8. Cocos2d-android (04) 执行多个动作

    先后.同时执行多个动作及动作序列执行结束后的事件 import org.cocos2d.actions.instant.CCCallFunc; import org.cocos2d.actions.i ...

  9. 【LeetCode】96 - Unique Binary Search Trees

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  10. WCF綁定

    服务之间的通信方式是多种多样的,有多种可能的通信模式.包括:同步的请求与应答(Request/Reply)消息,或者异步的即发即弃(Fire-and-Forget)消息等等,在通信时传输的消息编码格式 ...