通常IOC实现的步骤为-->建立容器-->加入组件-->获取组件-->使用组件.
1.建立容器
建立容器也就是IWindsorContainer.接着我门要向容器中注册服务,并告诉容器所注册的服务由那一个类来实现他.通常建立容器我们可以用以下定义来实现:
|
1 |
1IWindsorContainer container = new WindsorContainer(); |
2.加入组件
向建立好的容器里加入组件,直接调用容器的AddComponent()来完成.比如现在有一个写日志的接口ILog,实现这个服务的组件是TextLog,那我门可以通过如下方法把该组件加入到容器:
|
1 |
1container.AddComponent("txtLog", typeof(ILog), typeof(TextLog)); |
3.获取组件
获取组件可以直接通过加入组件的时候使用的key来获取,返回的是一个IWindsorContainer,这里需要一个强制转换.
|
1 |
1ILog log = (ILog)container["txtLog"]; |
4.使用组件
1//把当前时间写入到日志文件去
2log.Write(DateTime.Now.ToShortDateString()); 上面就是一个IOC容器的工作过程,从创建容器--加入组件--获取组件--使用组件.下面我看来看看一个小实例,也就是我在学习IOC的时候结合网上的资源自己小试牛刀瞎写的.
-------------------------------------------------------------------------------------------------------------
ILog接口(服务)的定义:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 |
1using System;2using System.Collections.Generic;3using System.Text;45namespace IOCDayOne6{7 /**//// <summary>8 /// 日志服务9 /// </summary>10 public interface ILog11 {12 /**//// <summary>13 /// 写日志方法14 /// </summary>15 /// <param
name="msgStr">日志内容</param>16 void Write(string msgStr);17 }18}19 |
TextLog组件的定义:
|
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 |
1namespace IOCDayOne2{3 /**//// <summary>4 /// ILog服务的组件5 /// </summary>6 public class TextFileLog:ILog7 {8 private string _target; //私有成员9 private ILogFormat _format; //ILogFormat一内聚的方式存在1011 /**//// <summary>12 /// 构造方法13 /// </summary>14 /// <param
name="target">标识</param>15 /// <param
name="format">提供格式化服务的接口</param>16 public TextFileLog(string target, ILogFormat format)17 {18 this._target = target;19 this._format = format;20 }2122 /**//// <summary>23 /// 写日志的实现方法24 /// </summary>25 /// <param
name="msgStr">日志内容</param>26 public void Write(string msgStr)27 {28 string str = _format.Format(msgStr); //格式化日志29 str += _target; //日志内容为格式化后的字符+类构造时传入的标识参数3031 //下面将日志记录到文本文件32 FileStream fs = new FileStream(this._target, FileMode.Append);33 StreamWriter sw = new StreamWriter(fs, Encoding.Default);34 sw.WriteLine("Log:-->" + str);35 sw.Close();36 }37 }38} |
XML配置文件的定义(指定将日志记录到C:Log.txt),TextLog组件需要存储路径的参数,我们在建立IOC容器的时候指定容器到这个配置文件中来找"target":
|
1
2
3
4
5
6
7
8
9
10
11 |
1<?xml
version="1.0"
encoding="utf-8"
?>2<configuration>3 <components>4 <component
id="txtLog">5 <parameters>6 <target>C:Log.txt</target>7 </parameters>8 </component>9 </components>10</configuration>11 |
出此之外还有一个格式化日志的服务IlogFormat,可将日志格式化为一定的格式输出,定义如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
1namespace IOCDayOne2{3 /**//// <summary>4 /// 格式化日志服务接口5 /// </summary>6 public interface ILogFormat7 {8 /**//// <summary>9 /// 格式化日志方法10 /// </summary>11 /// <param
name="msgStr">日志内容</param>12 /// <returns></returns>13 string Format(string msgStr);14 }15} |
实现ILogFormat服务的组件定义为:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
1namespace IOCDayOne2{3 public class TextFormat:ILogFormat4 {5 /**//// <summary>6 /// 格式化日志内容7 /// </summary>8 /// <param
name="msgStr">日志内容</param>9 /// <returns></returns>10 public string Format(string msgStr)11 {12 return "On:" + msgStr;13 }14 }15} |
到这里,来写个测试方法测试看看.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
1namespace IOCDayOne2{3 class Program4 {5 static void Main(string[] args)6 {7 //建立容器8 IWindsorContainer container = new WindsorContainer(new XmlInterpreter("<a
href=""http://www.cnblogs.com/Config/ConfigBase.xml/"">http://www.cnblogs.com/Config/ConfigBase.xml</a>"));9 //加入组件10 container.AddComponent("txtLog", typeof(ILog), typeof(TextFileLog));11 container.AddComponent("format", typeof(ILogFormat), typeof(TextFormat));12 //获取组件13 ILog log = (ILog)container["txtLog"];14 //使用组件15 log.Write(DateTime.Now.ToShortDateString());16 }17 }18} |
测试输出的结果为:
|
1 |
Log:-->On:2008-4-3C:Log.txt |
上面的main()中可以看书,在使用组件的时候只传递了一个参数(日志内容),而实现ILog服务的组件的构造方法是需要两个参数,
|
1
2
3
4
5
6
7
8
9
10 |
1/**//// <summary>2/// 构造方法3/// </summary>4/// <param
name="target">标识</param>5/// <param
name="format">提供格式化服务的接口</param>6public TextFileLog(string target, ILogFormat format)7{8 this._target = target;9 this._format = format;10} |
在前面向容器中注册ILog服务的时候,告诉容器TextFileLog实现了这个服务,这里还设置了一个key的参数,后面可以通过这个参数来获取这个服务,注册ILog时容器会发现这个服务依赖于其他的服务,它会自动去寻找,如果找不到这样的服务,则会抛出一个异常.
到这里,一个IOC的完整实例就完成了.其实还有另外一种方式实现.详细见下面.
-------------------------------------------------------------------------------------------------------------
上面是通过把配置写到XML的,而组件与服务是直接通过容器的加入组件来完成匹配.这样显然是不够灵活的,一单需求发生了变化,实现ILog服务的组件不在是TextFileLog的时候又该怎么处理呢?我们又去修改加入组件时的程序代码来实现,这样是可以达到需求的,但是这样做很明显不够灵活.那怎么做才能让服务去调用具体的实现组件修改方便呢?另一种方式是通过配置文件(App.config/Web.config)来实现.
下面是针对上面这个实例定义的App.config配置:
|
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 |
1<?xml
version="1.0"
encoding="utf-8"
?>2<configuration>3 <configSections>4 <section
name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,Castle.Windsor"/>5 </configSections>6 <castle>7 <components>8 <component
id="txtLog" service="IOCDayOne.ILog,IOCDayOne" type="IOCDayOne.TextFileLog,IOCDayOne">9 <parameters>10 <target>C:Log.txt</target>11 </parameters>12 </component>13 <component
id="format" service="IOCDayOne.ILogFormat,IOCDayOne" type="IOCDayOne.TextFormat,IOCDayOne">14 <paramters>15 <target>DayOne</target>16 </paramters>17 </component>18 </components>19 </castle>20</configuration> |
这时,测试方法就需要改动下了,通过配置文件来完成IOC,详细如下:
Castle学习笔记----初探IOC容器,布布扣,bubuko.com
原文:http://www.cnblogs.com/lvfeilong/p/Castle-8.html