• Castle IOC容器内幕故事(下)


    主要内容

      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有很大的好处,后续文章会讲到。

  • 相关阅读:
    velocity语法
    使用VS2003创建WEB程序的时候出现"AutoMation服务器不能创建对象"错误
    ASP.NET 2.0 Tips:跨页提交
    Tip #1 – 创建、管理、应用样式表的强大工具(Visual Studio 2008)
    解决ASP.NET2.0和1.1在同一台电脑上不能并行的问题
    Tip #2 - 样式应用工具(style application toolbar)
    利用HttpModuler实现WEB程序同一时间只让一个用户实例登陆
    ASP.NET Tips: 获取插入记录的ID
    通过rsync远程增量备份数据
    array_merge() [function.arraymerge]: Argument #1 is not an array in ……错误的解决办法
  • 原文地址:https://www.cnblogs.com/lvfeilong/p/Castle-7.html
Copyright © 2020-2023  润新知