Castle学习笔记----初探IOC容器

      Windsor是Castle 的一个IOC容器。它构建于MicroKernel之上,功能非常之强大,能检测类并了解使用这些类时需要什么参数,检测类型和类型之间工作依赖性,并提供服务或者发生错误时提供预警的机制。
      通常IOC实现的步骤为-->建立容器-->加入组件-->获取组件-->使用组件.

1.建立容器
     建立容器也就是IWindsorContainer.接着我门要向容器中注册服务,并告诉容器所注册的服务由那一个类来实现他.通常建立容器我们可以用以下定义来实现:
1 IWindsorContainer container  =   new  WindsorContainer();

2.加入组件
      向建立好的容器里加入组件,直接调用容器的 AddComponent()来完成.比如现在有一个写日志的接口ILog,实现这个服务的组件是TextLog,那我门可以通过如下方法把该组件加入到容器:
1 container.AddComponent( " txtLog " typeof (ILog),  typeof (TextLog));

3.获取组件
      获取组件可以直接通过加入组件的时候使用的key来获取,返回的是一个 IWindsorContainer,这里需要一个强制转换.
1 ILog log  =  (ILog)container[ " txtLog " ];

4.使用组件
1 // 把当前时间写入到日志文件去
2 log.Write(DateTime.Now.ToShortDateString());
     上面就是一个IOC容器的工作过程,从创建容器--加入组件--获取组件--使用组件.下面我看来看看一个小实例,也就是我在学习IOC的时候结合网上的资源自己小试牛刀瞎写的.
-------------------------------------------------------------------------------------------------------------
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

TextLog组件的定义:
Code
 1namespace IOCDayOne
 2{
 3    /**//// <summary>
 4    /// ILog服务的组件
 5    /// </summary>

 6    public class TextFileLog:ILog
 7    {
 8        private string _target;   //私有成员
 9        private ILogFormat _format; //ILogFormat一内聚的方式存在
10
11        /**//// <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        }

21
22        /**//// <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;    //日志内容为格式化后的字符+类构造时传入的标识参数
30
31            //下面将日志记录到文本文件
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 <? 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,可将日志格式化为一定的格式输出,定义如下:
Code
 1namespace IOCDayOne
 2{
 3    /**//// <summary>
 4    /// 格式化日志服务接口
 5    /// </summary>
 6    public interface ILogFormat
 7    {
 8        /**//// <summary>
 9        /// 格式化日志方法
10        /// </summary>
11        /// <param name="msgStr">日志内容</param>
12        /// <returns></returns>

13        string Format(string msgStr);
14    }

15}
实现ILogFormat服务的组件定义为:
Code
 1namespace IOCDayOne
 2{
 3    public class TextFormat:ILogFormat
 4    {
 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 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}

测试输出的结果为:
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时容器会发现这个服务依赖于其他的服务,它会自动去寻找,如果找不到这样的服务,则会抛出一个异常.
      到这里,一个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 >

这时,测试方法就需要改动下了,通过配置文件来完成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就学与此,笔记也记于此.小弟是刚开始着手学习这门技术,望园里前辈别见笑,我不赶搬门弄虎的写什么文章,这篇文章只是我的一篇学习笔记罢了.

本文示例代码下载

想学习Castle的朋友我建议去看看李会军老师的文章,本文部分内容也是来自他的blog.
Castle 开发系列文章
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值