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

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

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

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

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

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

    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
    实现ILogFormat服务的组件定义为:
    Code

    到这里,来写个测试方法测试看看.
     1namespace 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>

     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<?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,详细如下:
     1namespace 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 开发系列文章
  • 相关阅读:
    iOS开发代码规范
    数组去重方法总结
    iOS进阶学习-网络之数据安全
    OC 动态类型,动态绑定,动态加载
    ios运行某些工程时屏幕上下出现黑边的解决办法
    流程控制和数组(关于JAVA基础注意事项)
    高级函数
    源码
    sql s2 学期的学习
    Java 学习笔记
  • 原文地址:https://www.cnblogs.com/beniao/p/1135410.html
Copyright © 2011-2022 走看看