主要内容

  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. dede栏目调用大全

    A:侧边栏常用的当前栏目的父栏目调用(5.7) 1.在include/common.inc.php增加函数 function getTopCategoryName($cid=0) { global $ ...

  2. php 使用phpmailer 发送邮件(附带中文乱码的解决方法)

    下载phpmailer ,在程序里包含class.phpmailer.php 类  ,这里有中文乱码的解决方法 实例代码如下 <html> <head> <title&g ...

  3. JDBC用ResultSet访问大量数据时会遇到的问题

    我们经常需要JDBC来对数据库就行操作,一般流程为连接数据库.通过sql语句把需要的数据取出来保存到ResultSet,然后调用ResultSet方法的类似 getString,getInt()等方法 ...

  4. HDU 2151 Worm

    Worm Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...

  5. Yii连接多个数据库的方法

    一.配置多数据库 大多数情况下,我们都会采用同一类型的数据库,只是为了缓解压力分成主从或分布式形式而已.声明你可以在 主配置文件 ( main.php )   中里声明其它的数据库连接: <?p ...

  6. 搭建XMPP协议,实现自主推送消息到手机

    关于服务器端向Android客户端的推送,主要有三种方式: 1.客户端定时去服务端取或者保持一个长Socket,从本质讲这个不叫推送,这是去服务端拽数据.但是实现简单,主要缺点:耗电等 2.Googl ...

  7. 又一枚神器:nginx

    一直听说过nginx的大名,也自己装过,但是未直接使用其各种牛X的功能. 今天试用了一下,只能用两字感叹:牛逼!比如它提供的配置检查功能,真是贴心极了,又比如我想要的静态内容浏览器端缓存功能,动态内容 ...

  8. nginx 负载均衡相关知识

    Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 是由 Igor Sysoev ...

  9. 【转】Linux下创建、销毁、使用 SWAP

    转自:http://blog.csdn.net/wxqee/article/details/7970110 创建swap文件方法 1) 创建一个足够大的文件 dd if=/dev/zero of=/l ...

  10. CMDB反思5

    ITSM工具规划设计 http://blog.vsharing.com/xqscool/A946789.html 相比PPT中被管的数个对象(像培训什么的也都在其中),我们的需求其实就要小得多,但是问 ...