主要内容

  1.ComponentModelBuilder 和 Contributors

  2.Contributors分析

  3.Handles分析

  4.ComponentActivator分析

  一.ComponentModelBuilder 和 Contributors

  在前一篇中介绍组件的注册流程时说到了,创建ComponentModel的过程就是调用contributor来对组件进行处理的过程。Contributor就是我们这个内幕故事的第一个主角,在DefaultComponentModelBuilder一共注册了八个Contributor,每一个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() );
}

  1.ConfigurationModelInspector:用来处理配置,它使用ConfigurationStore在Kernel中注册来保持一个组件的连接。

  2.LifestyleModelInspector:生命周期处理方式,主要有Singleton、Thread、Transient、Pooled、Custom这些都可以在配置文件中指定,后续文章会讲到。

  3.ConstructorDependenciesModelInspector:处理构造函数依赖,收集所有的Public构造函数,并它们交给ComponentModel的Constructors集合。

  4.PropertiesDependenciesModelInspector:处理属性依赖,收集所有的可写的属性,Kernel也许不会在组件注册时就设置所有的属性,也有可能在请求获取组件时来设置。

  5.MethodMetaInspector:检测组件配置中的Method节点,每一个节点都将添加到ComponentModel的Method集合中。

  6.LifecycleModelInspector:处理组件生命周期,即在组件装载,初始化,销毁所出发的行为,分别对应三个接口:IInitializable,ISupportInitialize,IDisposable,如果组件实现了这些接口,容器会自动在不同的生命周期调用它们。

  7.ConfigurationParametersInspector:处理配置文件中的parameters元素内容,每一个parameters都将创建一个ParameterModel,并添加到ComponentModel的Parameters集合中。

  8.InterceptorInspector:处理InterceptorAttribute或者配置文件中的interceptors元素的信息。

  在有些情况下,我们可能并不需要这么多的Contributors,或者说我们想添加自定义的Contributors,可以用ComponentModelBuilder的如下两个方法来实现对Contributors的管理:

双击代码全选
1
2
3
4
5
6
7
8
9
public void AddContributor(IContributeComponentModelConstruction contributor)
{
  contributors.Add(contributor);
}
public void RemoveContributor(IContributeComponentModelConstruction contributor)
{
  contributors.Remove(contributor);
}

  二.Contributors分析

  通过上面的分析可以看到八个Contributors按一定顺序组合构成了整个组件的处理流程,现在我们来看一下Contributors是如何实现的?每一个Contributors都必须实现于接口IcontributeComponentModelConstruction,通过这个,我们可以创建自己的Contributors:

双击代码全选
1
2
3
4
5
public interface IContributeComponentModelConstruction
{
  void ProcessModel(IKernel kernel, ComponentModel model);
}

  来看一下其中LifecycleModelInspector的实现代码:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[Serializable]
public class LifecycleModelInspector : IContributeComponentModelConstruction
{
  public LifecycleModelInspector()
  {
  }
  public virtual void ProcessModel(IKernel kernel, ComponentModel model)
  {
    if (typeof (IInitializable).IsAssignableFrom(model.Implementation))
    {
      model.LifecycleSteps.Add( LifecycleStepType.Commission, InitializationConcern.Instance );
    }
    if (typeof (ISupportInitialize).IsAssignableFrom(model.Implementation))
    {
      model.LifecycleSteps.Add( LifecycleStepType.Commission, SupportInitializeConcern.Instance );
    }
    if (typeof (IDisposable).IsAssignableFrom(model.Implementation))
    {
      model.LifecycleSteps.Add( LifecycleStepType.Decommission, DisposalConcern.Instance );
    }
  }
}

至此,第一个主角Contributors的故事就完了。

  三.Handles分析

  在组件注册流程中,还提到了一个重要的角色就是Handles。对Handles的描述引用Castle官方网站的一句话来说就是“They don't construct the component themselves, but they know who does”。Handles它有两个状态,分别标识组件是否可以被请求还是需要继续等待相关的依赖,所有的Handles都必须实现IHandles接口,通过这个也可以创建自己的Handle。

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public enum HandlerState
{
  Valid,
  WaitingDependency
}
public interface IHandler
{
  void Init(IKernel kernel);
  object Resolve();
  void Release(object instance);
  HandlerState CurrentState { get; }
  ComponentModel ComponentModel { get; }
}

  Handles通过下面两个方法来检查哪些组件可以被请求,而哪些组件需要继续等待相关依赖,但是它并不做具体的组件创建工作。

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public override object Resolve()
{
  if (CurrentState == HandlerState.WaitingDependency)
  {
    String message =
      String.Format("Can't create component '{1}' as it has dependencies to be satisfied. {0}",
        ObtainDependencyDetails(), ComponentModel.Name );
    throw new HandlerException(message);
  } 
  return lifestyleManager.Resolve();
}
public override void Release(object instance)
{
  lifestyleManager.Release( instance );
}

  四.ComponentActivator分析

  介绍完前面三位角色之后,今天最后一位登场的主角就是ComponentActivator,组件激活器。每一个组件都和一个Activator相关联。Castle IOC为我们提供了默认的Activator,Castle IOC已经为我们提供了默认的Activator,但有时候也需要自己去实现Activator,比如说创建组件的实例并不是new出来的,而是通过我们自定义的Factory方法创建的,或者说我们需要创建的组件一个Remoting组件。创建自定义的Activator需要继承于AbstractComponentActivator基类或者DefaultComponentActivator。

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
[Serializable]
public abstract class AbstractComponentActivator : IComponentActivator
{
  private IKernel kernel;
  private ComponentModel model;
  private ComponentInstanceDelegate onCreation;
  private ComponentInstanceDelegate onDestruction;
  public AbstractComponentActivator(ComponentModel model, IKernel kernel,
    ComponentInstanceDelegate onCreation,
    ComponentInstanceDelegate onDestruction)
  {
    this.model = model;
    this.kernel = kernel;
    this.onCreation = onCreation;
    this.onDestruction = onDestruction;
  }
  public IKernel Kernel
  {
    get { return kernel; }
  }
  public ComponentModel Model
  {
    get { return model; }
  }
  public ComponentInstanceDelegate OnCreation
  {
    get { return onCreation; }
  }
  public ComponentInstanceDelegate OnDestruction
  {
    get { return onDestruction; }
  }
  protected abstract object InternalCreate();
  protected abstract void InternalDestroy(object instance);
  IComponentActivator Members#region IComponentActivator Members
  public virtual object Create()
  {
    object instance = InternalCreate();
    onCreation(model, instance);
    return instance;
  }
  public virtual void Destroy(object instance)
  {
    InternalDestroy(instance);
    onDestruction(model, instance);
  }
  #endregion
}

  关于Castle IOC内部主角分析就到这里了,至此Castle IOC的内幕故事也告一段落了,通过这两篇文章我们对Castle IOC的内幕有了一个简单的认识,这对于我们使用Castle IOC有很大的好处,后续文章会讲到。

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

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

    主要内容 1.WindsorContainer分析 2.MicroKernel分析 3.注册组件流程 一.WindsorContainer分析 WindsorContainer是Castle的IOC容 ...

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

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

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

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

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

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

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

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

  6. Castle IOC容器快速入门

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

  7. Castle IOC容器实践之FactorySupport Facility

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

  8. Castle学习笔记----初探IOC容器

    通常IOC实现的步骤为-->建立容器-->加入组件-->获取组件-->使用组件. 1.建立容器 建立容器也就是IWindsorContainer.接着我门要向容器中注册服务,并 ...

  9. .net core2.0下Ioc容器Autofac使用

    .net core发布有一段时间了,最近两个月开始使用.net core2.0开发项目,大大小小遇到了一些问题.准备写个系列介绍一下是如何解决这些问题以及对应技术.先从IOC容器Autofac开始该系 ...

随机推荐

  1. 【英语】Bingo口语笔记(60) - 口语中的浊化发音

  2. Android下监听Home键

    网上看到demo,亲测了以下机器和设备,均测试通过: 测试通过的手机: 1.华为荣耀3(Android 4.2.2) 2.小米2s(Android 4.1.1) 3.联想的手机 (Android2.3 ...

  3. linux 安装SVN

    1.环境centos6.4 2.安装svnyum -y install subversion 3.配置 建立版本库目录mkdir /www/svndata svnserve -d -r /www/sv ...

  4. MySQL与Oracle 差异比较之二基本语法

    基本语法 编号 类别 ORACLE MYSQL 注释 1 变量的声明方式不同 li_index NUMBER := 0 DECLARE li_index INTEGER DEFAULT 0 1. my ...

  5. Arduino命令行编译 树莓派连接Arduino 电脑上编译Arduino代码后 通过树莓派烧写到Arduino上

    //本教程针对UNO 1.在file->preferences中找到preferences.txt文件 2:用记事本打开preferences.txt,选择hex文件存放的路径,在最后行加入 b ...

  6. [转] C# 键盘中的按键对应的KeyValue

    原文C#KeyValue对应键盘 首先先看一下什么情况下需要对按键进行识别: KeyPress事件响应函数中,有KeyPressEventArgs, 对应于e.KeyChar; KeyDown事件响应 ...

  7. app如何节省流量

    前言:“客户端上传时间戳”的玩法,你玩过么?一起聊聊时间戳的奇技淫巧! 缘起:无线时代,流量敏感.APP在登录后,往往要向服务器同步非常多的数据,很费流量,技术上有没有节省流量的方法呢?这是本文要讨论 ...

  8. ansible条件使用--实践

    ansible条件使用 1.条件使用最简单的方式 ansible中使用条件最简单的方式如下所示: [root@ansibleserver kel]# cat conditions.yml --- - ...

  9. 2014搜狗前端面经【B事业部】

    本来就投了一份简历,后来又收到了个B事业部的面试电话,今天刚面完一面,总体感觉还是很基础的,其中一名面试官帅到不行啊!另一个也不差,真是幸胡...(sorry,跑题了...) 上来先做了份笔试题,超级 ...

  10. linux下expect使用教程

    一.expect介绍 Expect是Unix系统中用来进行自动化控制和测试的软件工具,由DonLibes制作,作为Tcl脚本语言的一个扩展,应用在交互式软件中如telnet,ftp,Passwd,fs ...