zoukankan      html  css  js  c++  java
  • Castle学习笔记----初探IOC容器

    通常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;
    4
    5namespace 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组件的定义:

    双击代码全选
    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 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
    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 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服务的组件定义为:

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    1namespace IOCDayOne
    2{
    3  class Program
    4  {
    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,详细如下:

    本文示例代码或素材下载

  • 相关阅读:
    C#生成唯一码方法
    解剖常用软件程序都用什么语言开发
    Unity3D笔记七 GUILayout
    函数的递归
    函数
    函数的参数
    函数的返回值
    函数的定义
    文件处理
    集合
  • 原文地址:https://www.cnblogs.com/lvfeilong/p/Castle-8.html
Copyright © 2011-2022 走看看