天天看點

Castle IOC容器實踐之Startable Facility(一)

摘要:從本文開始,我們将逐一實踐Castle IOC中的Facility,在前面我們說過,Facility它是帶有注入性質的。有時我們會遇到這樣的問題,當一個元件滿足一定的依賴關系之後,讓它 自動運作,比如說啟動一個窗體或者啟動某種服務,本文我們就來看如何使用Startable Facility讓一個實作了接口IStartable的元件自動運作,以及不實作IStartable接口的元件如何在滿足依賴後自動運作。

主要内容

1.Startable Facility概述

2.實作IStartable接口使用詳解

3.不實作IStartable接口使用

一.Startable Facility概述

在開始使用Startable Facility之前,我們先了解一下它做了什麼事情,它可以讓一個元件在滿足依賴關系之後自動啟動或者停止。官方網站中提供的Startable Facility的有關資訊:

Facility Information
Uses Proxy No
Requires Configuration No
Uses Attributes No
Version Beta 2

二.實作IStartable接口使用詳解

Startable Facility的使用可以說是非常地簡單,隻要我們的元件實作了IStartable接口就可以了。現在我們還有一個Program類,它專門控制 Server的啟動和停止,我們希望在它的依賴關系滿足後,讓Server自動啟動。很簡單,我們讓Program類實作IStartable接口:

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// <summary>

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// Author:Terrylee

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// Date:2006年4月28日

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// From:http://terrylee.cnblogs.com

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// </summary>

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

public   class  Program : IStartable

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

    private Server _server;

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    public Program(Server server)

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

        this._server = server;

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    public void Start()

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

        _server.Start();

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    public void Stop()

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

        _server.Stop();

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)

}

注意這個裡面的Start()和Stop()方法就是要實作接口中的方法,我們在Start()方法中啟動伺服器,在Stop()方法中停止伺服器。并且這個類依賴于Server類,也就是要滿足它的依賴關系,還需要有一個Server元件。伺服器Server,它需要一個Host和Port:

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// <summary>

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// Author:Terrylee

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// Date:2006年4月28日

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// From:http://terrylee.cnblogs.com

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// </summary>

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

public   class  Server

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

    private string _host;

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    private int _port;

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    public Server(string host,int port)

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

        this._host = host;

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        this._port = port;

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    public void Start()

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

        Console.WriteLine("Server {0}:{1} Start

Castle IOC容器實踐之Startable Facility(一)

",_host,_port);

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        Console.ReadLine();

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    public void Stop()

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

        Console.WriteLine("Server {0}:{1} Stop

Castle IOC容器實踐之Startable Facility(一)

",_host,_port);

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        Console.ReadLine();

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)

}

同時對于這個Server類來說,它需要一個配置檔案:

Castle IOC容器實踐之Startable Facility(一)

<!-- From:http://terrylee.cnblogs.com -->

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

<? xml version="1.0" encoding="utf-8"  ?>

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

< configuration >

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

     < components >

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

         < component  id ="server" >

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

             < parameters >

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

                 < host > localhost </ host >

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

                 < port > 110 </ port >

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

             </ parameters >

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

         </ component >

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

     </ components >

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

</ configuration >

需要注意的是這個配置檔案跟Startable Facility沒有任何關系,我們在配置檔案中看不到任何和Startable Facility有關的代碼。它隻是一個普通的Castle IOC配置檔案,因為我們在概述中已經說過了,Startable Facility是不需要配置檔案的。好了,現在我們來看客戶程式的使用:

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// <summary>

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// Author:Terrylee

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// Date:2006年4月28日

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// From:http://terrylee.cnblogs.com

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

/// </summary>

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

public   class  App

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

    public static void Main() 

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

        //建立Windsor容器

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        IWindsorContainer container = new WindsorContainer(new XmlInterpreter("http://www.cnblogs.com/BasicUsage.xml"));        

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        //添加Facility

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        container.AddFacility("startable", new StartableFacility());       

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        //添加Program元件 (A)

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        container.AddComponent("program", typeof(Program));      

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        //添加Server元件(B)

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        container.AddComponent("server", typeof(Server));

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)

}

可以看到,在這個過程中,沒有一點多餘的代碼,首先添加Startable Facility到容器中,然後添加Program元件,即執行到上面的A句的時候,因為還沒有添加Server元件,不滿足它的依賴關系,是以它無法啟動,當添加完Server元件後,即執行了B句後,滿足了它的依賴關系,這個它才會自動執行。

三.不實作IStartable接口使用

這是個很多人都忽略的問題,開始時我一直認為隻有實作了IStartable接口才能使用Startable Facility,後來我在讀它的源碼時發現了一個問題,它不僅僅是判斷元件是否實作了這個接口,如果元件有Startable特性也可以在滿足依賴性後 自動啟動,這個在下一篇原理分析篇中我會介紹到。然後我就去查找這方面的資料,很可惜的網上從來沒有介紹這種使用方法,我從它的TestCase找到了一 點下面的代碼,供有興趣的朋友參考一下:

沒有實作IStartable接口的元件:

Castle IOC容器實踐之Startable Facility(一)

[Transient]

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

public   class  NoInterfaceStartableComponent

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

    private bool _Started = false;

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    private bool _Stopped = false;

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    public void Start()

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

        _Started = true;

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    public void Stop()

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

        _Stopped = true;

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    public bool Started

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        get 

Castle IOC容器實踐之Startable Facility(一)

{ return _Started; }

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    public bool Stopped

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

        get 

Castle IOC容器實踐之Startable Facility(一)

{ return _Stopped; }

Castle IOC容器實踐之Startable Facility(一)

    }

Castle IOC容器實踐之Startable Facility(一)

}

測試代碼:

Castle IOC容器實踐之Startable Facility(一)

[Test]

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

public   void  TestComponentWithNoInterface()

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

{

Castle IOC容器實踐之Startable Facility(一)

    IKernel kernel = new DefaultKernel();

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    MutableConfiguration compNode = new MutableConfiguration("component");

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    compNode.Attributes["id"] = "b";

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    compNode.Attributes["startable"] = "true";

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    compNode.Attributes["startMethod"] = "Start";

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    compNode.Attributes["stopMethod"] = "Stop";

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    kernel.ConfigurationStore.AddComponentConfiguration("b", compNode);

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    kernel.AddFacility( "startable", new StartableFacility() );

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    kernel.AddComponent( "b", typeof(NoInterfaceStartableComponent) );

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    NoInterfaceStartableComponent component = kernel["b"] as NoInterfaceStartableComponent;

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    Assert.IsNotNull(component);

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    Assert.IsTrue( component.Started );

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    Assert.IsFalse( component.Stopped );

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    kernel.ReleaseComponent(component);

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

    Assert.IsTrue( component.Stopped );

Castle IOC容器實踐之Startable Facility(一)
Castle IOC容器實踐之Startable Facility(一)

}

對于IKrnel大家可以自行修改為Castle.Windsor,這樣也不失為一種使用Startable Facility的方法。