Castle学习笔记----初探IOC容器
Windsor是Castle 的一个IOC容器。它构建于MicroKernel之上,功能非常之强大,能检测类并了解使用这些类时需要什么参数,检测类型和类型之间工作依赖性,并提供服务或者发生错误时提供预警的机制。
通常IOC实现的步骤为-->建立容器-->加入组件-->获取组件-->使用组件.
1.建立容器
建立容器也就是IWindsorContainer.接着我门要向容器中注册服务,并告诉容器所注册的服务由那一个类来实现他.通常建立容器我们可以用以下定义来实现:
2.加入组件
向建立好的容器里加入组件,直接调用容器的AddComponent()来完成.比如现在有一个写日志的接口ILog,实现这个服务的组件是TextLog,那我门可以通过如下方法把该组件加入到容器:
3.获取组件
获取组件可以直接通过加入组件的时候使用的key来获取,返回的是一个IWindsorContainer,这里需要一个强制转换.
4.使用组件
-------------------------------------------------------------------------------------------------------------
ILog接口(服务)的定义:
TextLog组件的定义:
Code
XML配置文件的定义(指定将日志记录到C:\Log.txt),TextLog组件需要存储路径的参数,我们在建立IOC容器的时候指定容器到这个配置文件中来找"target":
出此之外还有一个格式化日志的服务IlogFormat,可将日志格式化为一定的格式输出,定义如下:
Code
实现ILogFormat服务的组件定义为:
Code
到这里,来写个测试方法测试看看.
测试输出的结果为:
Log:-->On:2008-4-3C:\Log.txt
上面的main()中可以看书,在使用组件的时候只传递了一个参数(日志内容),而实现ILog服务的组件的构造方法是需要两个参数,
到这里,一个IOC的完整实例就完成了.其实还有另外一种方式实现.详细见下面.
-------------------------------------------------------------------------------------------------------------
上面是通过把配置写到XML的,而组件与服务是直接通过容器的加入组件来完成匹配.这样显然是不够灵活的,一单需求发生了变化,实现ILog服务的组件不在是TextFileLog的时候又该怎么处理呢?我们又去修改加入组件时的程序代码来实现,这样是可以达到需求的,但是这样做很明显不够灵活.那怎么做才能让服务去调用具体的实现组件修改方便呢?另一种方式是通过配置文件(App.config/Web.config)来实现.
下面是针对上面这个实例定义的App.config配置:
这时,测试方法就需要改动下了,通过配置文件来完成IOC,详细如下:
本文示例代码下载
想学习Castle的朋友我建议去看看李会军老师的文章,本文部分内容也是来自他的blog.
Castle 开发系列文章
通常IOC实现的步骤为-->建立容器-->加入组件-->获取组件-->使用组件.
1.建立容器
建立容器也就是IWindsorContainer.接着我门要向容器中注册服务,并告诉容器所注册的服务由那一个类来实现他.通常建立容器我们可以用以下定义来实现:
1
IWindsorContainer container = new WindsorContainer(![]()
![]()
);
IWindsorContainer container = new WindsorContainer(

);2.加入组件
向建立好的容器里加入组件,直接调用容器的AddComponent()来完成.比如现在有一个写日志的接口ILog,实现这个服务的组件是TextLog,那我门可以通过如下方法把该组件加入到容器:
1
container.AddComponent("txtLog", typeof(ILog), typeof(TextLog));
container.AddComponent("txtLog", typeof(ILog), typeof(TextLog));3.获取组件
获取组件可以直接通过加入组件的时候使用的key来获取,返回的是一个IWindsorContainer,这里需要一个强制转换.
1
ILog log = (ILog)container["txtLog"];
ILog log = (ILog)container["txtLog"];4.使用组件
1
//把当前时间写入到日志文件去
2
log.Write(DateTime.Now.ToShortDateString());
上面就是一个IOC容器的工作过程,从创建容器--加入组件--获取组件--使用组件.下面我看来看看一个小实例,也就是我在学习IOC的时候结合网上的资源自己小试牛刀瞎写的.
//把当前时间写入到日志文件去2
log.Write(DateTime.Now.ToShortDateString());-------------------------------------------------------------------------------------------------------------
ILog接口(服务)的定义:
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4![]()
5
namespace IOCDayOne
6
{
7
/// <summary>
8
/// 日志服务
9
/// </summary>
10
public interface ILog
11
{
12
/// <summary>
13
/// 写日志方法
14
/// </summary>
15
/// <param name="msgStr">日志内容</param>
16
void Write(string msgStr);
17
}
18
}
19![]()
using System;2
using System.Collections.Generic;3
using System.Text;4

5
namespace 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组件的定义:
XML配置文件的定义(指定将日志记录到C:\Log.txt),TextLog组件需要存储路径的参数,我们在建立IOC容器的时候指定容器到这个配置文件中来找"target":
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![]()
<?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
namespace IOCDayOne
2
{
3
class Program
4
{
5
static void Main(string[] args)
6
{
7
//建立容器
8
IWindsorContainer container = new WindsorContainer(new XmlInterpreter("http://www.cnblogs.com/Config/ConfigBase.xml"));
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
}
namespace IOCDayOne2
{3
class Program4
{5
static void Main(string[] args)6
{7
//建立容器8
IWindsorContainer container = new WindsorContainer(new XmlInterpreter("http://www.cnblogs.com/Config/ConfigBase.xml"));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
}测试输出的结果为:
Log:-->On:2008-4-3C:\Log.txt
上面的main()中可以看书,在使用组件的时候只传递了一个参数(日志内容),而实现ILog服务的组件的构造方法是需要两个参数,
1
/// <summary>
2
/// 构造方法
3
/// </summary>
4
/// <param name="target">标识</param>
5
/// <param name="format">提供格式化服务的接口</param>
6
public TextFileLog(string target, ILogFormat format)
7
{
8
this._target = target;
9
this._format = format;
10
}
在前面向容器中注册ILog服务的时候,告诉容器TextFileLog实现了这个服务,这里还设置了一个key的参数,后面可以通过这个参数来获取这个服务,注册ILog时容器会发现这个服务依赖于其他的服务,它会自动去寻找,如果找不到这样的服务,则会抛出一个异常.
/// <summary>2
/// 构造方法3
/// </summary>4
/// <param name="target">标识</param>5
/// <param name="format">提供格式化服务的接口</param>6
public TextFileLog(string target, ILogFormat format)7
{8
this._target = target;9
this._format = format;10
}到这里,一个IOC的完整实例就完成了.其实还有另外一种方式实现.详细见下面.
-------------------------------------------------------------------------------------------------------------
上面是通过把配置写到XML的,而组件与服务是直接通过容器的加入组件来完成匹配.这样显然是不够灵活的,一单需求发生了变化,实现ILog服务的组件不在是TextFileLog的时候又该怎么处理呢?我们又去修改加入组件时的程序代码来实现,这样是可以达到需求的,但是这样做很明显不够灵活.那怎么做才能让服务去调用具体的实现组件修改方便呢?另一种方式是通过配置文件(App.config/Web.config)来实现.
下面是针对上面这个实例定义的App.config配置:
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>
<?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,详细如下:
1
namespace IOCDayOne
2
{
3
class Program
4
{
5
static void Main(string[] args)
6
{
7
//建立容器,并通过配置文件最动加入组件
8
IKernel kernel;
9
Castle.Core.Resource.ConfigResource source = new Castle.Core.Resource.ConfigResource();
10
XmlInterpreter interpreter = new XmlInterpreter(source);
11
WindsorContainer windsor = new WindsorContainer(interpreter);
12
kernel = windsor.Kernel;
13![]()
14
//获取组件
15
ILog log = (ILog)kernel["txtLog"];
16![]()
17
//使用组件
18
log.Write(DateTime.Now.ToShortDateString());
19
}
20
}
21
}
今天的IOC就学与此,笔记也记于此.小弟是刚开始着手学习这门技术,望园里前辈别见笑,我不赶搬门弄虎的写什么文章,这篇文章只是我的一篇学习笔记罢了.
namespace IOCDayOne2
{3
class Program4
{5
static void Main(string[] args)6
{7
//建立容器,并通过配置文件最动加入组件8
IKernel kernel;9
Castle.Core.Resource.ConfigResource source = new Castle.Core.Resource.ConfigResource();10
XmlInterpreter interpreter = new XmlInterpreter(source);11
WindsorContainer windsor = new WindsorContainer(interpreter);12
kernel = windsor.Kernel;13

14
//获取组件15
ILog log = (ILog)kernel["txtLog"];16

17
//使用组件18
log.Write(DateTime.Now.ToShortDateString());19
}20
}21
}本文示例代码下载
想学习Castle的朋友我建议去看看李会军老师的文章,本文部分内容也是来自他的blog.
Castle 开发系列文章

浙公网安备 33010602011771号