zoukankan      html  css  js  c++  java
  • Castle IOC容器构建配置详解(二)

    主要内容

      1.基本类型配置

      2.Array类型配置

      3.List类型配置

      4.Dictionary类型配置

      5.自定义类型转换

      一.基本类型配置

      在Castle IOC的配置文件中,大家可能都已经注意一个问题了,就是不管组件接收的是什么基本数据类型,我们一律没有在配置文件中指定,也就是说,不管组件接收的类型是int型或者是String类型,我们都可以这样去配置:

    双击代码全选
    1
    2
    3
    4
    5
    <component id="MyComponent">
      <parameters>
        <port>10</port>
      </parameters>
    </component>

      这是因为在Castle IOC中,MicroKernel中的SubSystem中有一个TypeConverter,它专门负责类型的转换。参数的注入一般都是通过构造函数或者公有的属性,基本数据类型在配置文件我们不需要用专门的节点去配置,但是对于一些复杂的数据类型久有些不一样。目前Castle IOC能够支持的数据类型如下。

    类型 节点 示例
    System.Int32, Int16, Int64 - <parameters>

      <port>10</port>

      </parameters>

    System.UInt32, UInt16, UInt64 - <parameters>

      <port>10</port>

      </parameters>

    System.Char - <parameters>

      <letter>a</letter>

      </parameters>

    System.Single, Double, Decimal - <parameters>

      <threshold>13.22</threshold>

      </parameters>

    System.String - <parameters>

      <server>mail.host.com</server>

      </parameters>

    System.Byte, SByte - <parameters>

      <rcolor>144</rcolor>

      </parameters>

    System.Boolean - <parameters>

      <enabled>0</enabled>

      </parameters>

    System.DateTime - <parameters>

      <initial>11022005</initial>

      </parameters>

    System.Type - <parameters>

      <type>Components.MyComponent, Components</type>

      </parameters>

    System.Array array 参见后面
    System.Collections.IList list 参见后面
    System.Collections.IDictionary dictionary 参见后面

      如果有其它的类型,我们需要编写自定义的TypeConverter。

      二.Array类型配置

      组件构造函数有一个Array的参数

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class MyComponent
    {
      private int[] orders;
      public int[]Orders
      {
        get{ return this.orders;}
      }
      public MyComponent()
      {
      }
      public MyComponent(int[]orders)
      {
        this.orders = orders;
      }
    }

      这时候我们的配置文件可以如下去写

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <component id="e" type="CastleDemo.MyComponent,CastleDemo">
        <parameters>
          <Orders>
            <item type="System.Int32">
              <item>1</item>
              <item>2</item>
              <item>3</item>
            </item>
          </Orders>
        </parameters>
      </component>
    </configuration>

      三.List类型配置

      组件构造函数有一个IList类型的参数

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class MyComponent
    {
      private IList _hosts;
      public MyComponent(IList hosts)
      {
        this._hosts = hosts;
      }
      public IList Hosts
      {

      这时候我们的配置文件应该如下

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <component id="mycomponent" type="CastleDemo.MyComponent,CastleDemo">
        <parameters>
          <hosts>
            <list type="System.String">
              <item>server1</item>
              <item>server2</item>
              <item>server3</item>
              <item>server4</item>
            </list>
          </hosts>
        </parameters>
      </component>
    </configuration>

    四.Dictionary类型配置

      组件构造函数有一个Idictionary类型的参数

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class MyComponent
    {
      private IDictionary _dictionary;
      public MyComponent(IDictionary d)
      {
        this._dictionary = d;
      }
      public IDictionary Dictionary
      {
        get{ return this._dictionary;}
      }
      //
    }

    配置文件应该如下去写:

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <component id="MyComponent" type="CastleDemo.MyComponent,CastleDemo">
        <parameters>
          <d>
            <dictionary>
              <entry key="a">a</entry>
              <entry key="b">b</entry>
              <entry key="c">c</entry>
            </dictionary>
          </d>
        </parameters>
      </component>
    </configuration>

      或者我们可以在配置文件中分别指定Key和Value的数据类型,分别使用keyType和valueType。

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <component id="MyComponent" type="CastleDemo.MyComponent,CastleDemo">
        <parameters>
          <d>
            <dictionary keyType="System.String, mscorlib" valueType="System.String, mscorlib">
              <entry key="a">a</entry>
              <entry key="b">b</entry>
              <entry key="c">c</entry>
            </dictionary>
          </d>
        </parameters>
      </component>
    </configuration>

      五.自定义类型转换

      要实现我们自定义的类型转换,在这之前我们还是花一点时间来看看Castle IOC中是如何实现类型的转换的。在SubSystems中有一个Conversion,专门负责类型的转换,通过一个类型转换器ConversionManager来实现对类型转换的管理,在DefaultConversionManager初始化的时候,会加载以下几个类型转换:

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    protected virtual void InitDefaultConverters()
    {
      Add( new PrimitiveConverter() );
      Add( new TypeNameConverter() );
      Add( new EnumConverter() );
      Add( new ListConverter() );
      Add( new DictionaryConverter() );
      Add( new ArrayConverter() );
    }

      这些类型转换器之间的结构图如下:

      图1

      PrimitiveConverter:负责基本数据类型的转换

      TypeNameConverter:负责把一个类型的名字转换成这个类型的实例

      EnumConverter:负责枚举类型的转换

      ListConverter:负责Ilist数据类型的转换

      DictionaryConverter:负责Idictionary数据类型转换

      ArrayConverter:负责Array数据类型转换

      以其中的PrimitiveConverter为例来看一下它的实现代码:

    双击代码全选
    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
    public class PrimitiveConverter : AbstractTypeConverter
    {
      private Type[] types;
      public PrimitiveConverter()
      {
        types = new Type[]
          {
            typeof (Char),
            typeof (DateTime),
            typeof (Decimal),
            typeof (Boolean),
            typeof (Int16),
            typeof (Int32),
            typeof (Int64),
            typeof (UInt16),
            typeof (UInt32),
            typeof (UInt64),
            typeof (Byte),
            typeof (SByte),
            typeof (Single),
            typeof (Double),
            typeof (String)
          };
      }
      public override bool CanHandleType(Type type)
      {
        return Array.IndexOf(types, type) != -1;
      }
      public override object PerformConversion(String value, Type targetType)
      {
        if (targetType == typeof(String)) return value;
        try
        {
          return Convert.ChangeType(value, targetType);
        }
        catch(Exception ex)
        {
          String message = String.Format(
            "Could not convert from '{0}' to {1}",
            value, targetType.FullName);
          throw new ConverterException(message, ex);
        }
      }
      public override object PerformConversion(IConfiguration configuration, Type targetType)
      {
        return PerformConversion(configuration.Value, targetType);
      }
    }

      可以看到,Castle IOC会把所有的配置参数都当作String类型接收,如果目标类型是String,则直接返回结果,否则再进行类型转换。由此我们可以分析得出,要实现自己的类型转换,有以下两步:

      1.编写的自己的类型转换类,实现接口ITypeConverter

    双击代码全选
    1
    2
    3
    4
    public class MyTypeConverter : ITypeConverter
    {
      //
    }

      2.添加自己的类型转换到ConversionManager中

    双击代码全选
    1
    2
    3
    4
    IKernel kernel = new DefaultKernel();
    IConversionManager conversionMng = (IConversionManager)
      kernel.GetSubSystem( SubSystemConstants.ConversionManagerKey );
    conversionMng.Add(new MyTypeConverter());

      关于Castle IOC容器中构建配置信息就到这里了,我总共分为了一,二两部分来讲解。Castle IOC系列的文章后续还有很多,希望大家继续关注!

  • 相关阅读:
    灵魂拷问!浏览器输入「xxxxhub」的背后.....
    趣谈 DHCP 协议,有点意思。
    规约模式,颤抖吧产品经理!再也不怕你乱改需求了
    订阅者模式,公众号、B站、快手用了都说好!
    设计模式,你相信吗,只用两个函数实现事务!
    Linux系统中安装Jenkins
    Linux系统在线安装和查看git版本
    VIM中的保存和退出命令
    @JsonProperty爆红
    手动运行jar包
  • 原文地址:https://www.cnblogs.com/lvfeilong/p/Castle-5.html
Copyright © 2011-2022 走看看