主要內容
1.基本類型配置
2.Array類型配置
3.List類型配置
4.Dictionary類型配置
5.自定義類型轉換
一.基本類型配置
在Castle IOC的配置文件中,大家可能都已經注意一個問題了,就是不管組 件接收的是什麼基本數據類型,我們一律沒有在配置文件中指定,也就是說,不 管組件接收的類型是int型或者是String類型,我們都可以這樣去配置:
<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>
&l t;/parameters>
System.Single, Double, Decimal
-
<parameters>
<threshold>13.22</threshold>
</parameters>
System.String
-
<parameters>
<server>mail.host.com</server&g t;
</parameters>
System.Byte, SByte
-
<parameters>
<rcolor>144</rcolor>
</parameters>
System.Boolean
-
<parameters>
<enabled>0</enabled>
</parameters>
System.DateTime
-
<parameters>
<initial>11022005</initial>< br>
</parameters>
System.Type
-
<parameters>
<type>Components.MyComponent, Components</type>
</parameters>
System.Array
array
參見後面
System.Collections.IList
list
參見後面
System.Collections.IDictionary
dictionary
參見後面
如果有其它的類型,我們需要編寫自定義的TypeConverter。
二.Array類型配置
組件構造函數有一個Array的參數
public class MyComponent
{
private int[] orders;
public int[]Orders
{
get{ return this.orders;}
}
public MyComponent()
{
}
public MyComponent(int[]orders)
{
this.orders = orders;
}
}
這時候我們的配置文件可以如下去寫
<?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類型的參數
public class MyComponent
{
private IList _hosts;
public MyComponent(IList hosts)
{
this._hosts = hosts;
}
public IList Hosts
{
這時候我們的配置文件應該如下
<?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類型的參數
public class MyComponent
配置文件應該如下去寫:
{
private IDictionary _dictionary;
public MyComponent(IDictionary d)
{
this._dictionary = d;
}
public IDictionary Dictionary
{
get{ return this._dictionary;}
}
//
}
<?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。
<?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初始化的時候,會加載以下幾個類型轉換:
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為例來看一下它的實現代碼:
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
public class MyTypeConverter : ITypeConverter
{
//
}
2.添加自己的類型轉換到ConversionManager中
IKernel kernel = new DefaultKernel();
IConversionManager conversionMng = (IConversionManager)
kernel.GetSubSystem( SubSystemConstants.ConversionManagerKey );
conversionMng.Add(new MyTypeConverter());
關於Castle IOC容器中構建配置信息就到這裡了,我總共分為了一,二兩部 分來講解。Castle IOC系列的文章後續還有很多,希望大家繼續關注!