摘要:在快速入门指南篇中,我们对于Castle IOC容器的使用已经有了一个直观的认识。本文将在这基础上进一步对Castle IOC容器的结构及其注册组件的过程做一个深入的分析,让我们开始Castle IOC的内幕故事吧。

 
主要内容
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);

}

// [url]http://terrylee.cnblogs.com[/url]

可以看到,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);

}

// [url]http://terrylee.cnblogs.com[/url]
先做一些必要的异常处理,然后为当前组件创建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;
}
// [url]http://terrylee.cnblogs.com[/url]

创建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() );

}

// [url]http://terrylee.cnblogs.com[/url]
这八个Contributor形成了一个处理组件的流程,它们涵盖了组件处理流程中的配置,生命周期,构造函数依赖,属性依赖等方面,每一个Contributor只负责某一方面的事情。再下来一步就是发出ComponentModelCreated事件了,这步的操作很简单
protected virtual void RaiseComponentModelCreated(ComponentModel model)

{

    ComponentModelDelegate eventDelegate = (ComponentModelDelegate) events[ComponentModelCreatedEvent];

    if (eventDelegate != null) eventDelegate(model);

}

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

{

    IHandler handler = new DefaultHandler(model);

    handler.Init(kernel);

    return handler;

}

// [url]http://terrylee.cnblogs.com[/url]
最后发出ComponentRegistered、HandlerRegistered事件,完成整个组件的注册过程。
Castle IOC容器内幕故事(下)   
参考资料

Castle的官方网站[url]http://www.castleproject.org[/url]

本文转自lihuijun51CTO博客,原文链接:http://blog.51cto.com/terrylee/67672 ,如需转载请自行联系原作者

Castle IOC容器内幕故事(上)相关推荐

  1. Castle实践9-在Castle IOC容器中使用AspectSharp(全面剖析AspectSharp Facility)

    在"Castle实践8"介绍了A#的使用方法,那么A#如何和Castle IOC容器结合起来使用呢?在Castle的官方falicicies库中,提供了AspectSharp Fa ...

  2. Castle IOC容器快速入门

    摘要:IOC模式是近年来非常流行的一种模式,相信大家都不陌生了,如果你还不是很熟悉的话,可以看看Martin Fowler大师的文章http://martinfowler.com/articles/i ...

  3. Castle IOC容器实践之TypedFactory Facility(一)

    摘要:相信大家对于Factory Method设计模式都已经不陌生了,在Factory Method中,对于每一个具体的产品都需要有一个与之对应的工厂类,随着具体的产品越来越多,我们对于工厂类的管理就 ...

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

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

  5. Castle IOC容器实践之EnterpriseLibrary Configuration Facility

    摘要:EnterpriseLibrary Configuration Facility就好像是在容器和数据类之间的桥,让我们可以轻松得去读取和操作配置文件.熟悉Enterprise Library的人 ...

  6. [Spring 深度解析]第6章 Spring的IoC容器系列

    6. Spring的IoC容器系列 ​ IoC容器为开发者管理对象之间的依赖关系提供了很多便利和基础服务.有许多IoC容器供开发者选择,SpringFramework的IoC核心就是其中一个,它是开源 ...

  7. 抛开 Spring 去理解 IOC 思想:原来 IOC 容器这么简单

    很多小伙伴们看到标题可能就会想到抛开 Spring 就不会存在 IOC 思想了,其实不然在接下来的文章中就会讲述到. 很多小伙伴在理解 IOC 的时候通常会和 Spring 放到一起去学习,首先呢 S ...

  8. ioc spring 上机案例_抛开Spring去理解IOC思想 - 原来IOC容器这么简单

    很多小伙伴们看到标题可能就会想到抛开Spring就不会存在IOC思想了,其实不然在接下来的文章中就会讲述到. 很多小伙伴在理解IOC的时候通常会和Spring放到一起去学习,首先呢Spring设计的非 ...

  9. 【Spring】IoC容器系列的设计与实现:BeanFactory和ApplicationContext

    在Spring IoC容器的设计中,我们可以看到两个主要的容器系列,一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器的最基本功能,另一个是ApplicationContext ...

最新文章

  1. mysql or的效率_Mysql比较exists与in以及or的效率分析
  2. Flink从Kafka 0.8中读取多个Topic时的问题
  3. ASP.NET MVC 4高级编程(第4版)
  4. maven工程src/main/java目录无法创建问题
  5. P3385 【模板】负环
  6. java设置断点,在Java中设置断点
  7. redis学习之三配置文件redis.conf 的含义
  8. vue3打包后无法加载页面
  9. 判断表达式是否正确闭合,返回未闭合元素的下标。
  10. Linux 的字符串截取很有用。有八种方法。
  11. android6.0系统Healthd深入分析
  12. 腾讯产培课堂|产品经理岗位解析×面试指南
  13. SVM多分类的几种方式
  14. 飞思卡尔单片机学习记录(一)
  15. java关闭自动更新_怎么关闭java自动更新
  16. “双一流”高校,整体搬迁!
  17. 笔记本安装win10+ubuntu双系统超详细教程
  18. 阿里云Centos7修改22默认端口
  19. 大华SDK+JAVA+4g网络摄像头进行二次开发
  20. 基于红外遥控的arduino遥控小车

热门文章

  1. SAP Forecasting and Replenishment for Retail – A short Overview【中英文双语版】
  2. 南京、苏州、杭州、上海你更喜欢哪座城市?
  3. 专利申请超全球!新崛起的中国人工智能,还有哪些你不知道的事
  4. 人工智能基础-概率分布与函数的基础定义
  5. Caffe 运行平台支持DenseNet模型
  6. 头条丨2017年人工智能现七大走向
  7. 没有安装python如何使用anaconda运行python命令行
  8. 死前真的会有「跑马灯」,人类首次同步测量大脑濒死状态
  9. 华人一作统一「视觉-语言」理解与生成:一键生成图像标注,完成视觉问答,Demo可玩...
  10. 元宇宙不是下一代互联网,而是人类群体思维空间或梦境世界的具现