程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Castle學習筆記----初探IOC容器

Castle學習筆記----初探IOC容器

編輯:關於.NET

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組件的定義:

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,可將日志格式化為一定的格式輸出,定義如下:

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服務的組件定義為:

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}

到這裡,來寫個測試方法測試看看.

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就學與此,筆記也記於此.小弟是剛開始著手學習這門技術,望園裡前輩別見笑,我不趕搬門弄虎的寫什麼文章,這篇文章只是我的一篇學習筆記罷了.

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved