摘要:從本文開始,我們将逐一實踐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接口:
/// <summary>
/// Author:Terrylee
/// Date:2006年4月28日
/// From:http://terrylee.cnblogs.com
/// </summary>
public class Program : IStartable
{
private Server _server;
public Program(Server server)
{
this._server = server;
}
public void Start()
{
_server.Start();
}
public void Stop()
{
_server.Stop();
}
}
注意這個裡面的Start()和Stop()方法就是要實作接口中的方法,我們在Start()方法中啟動伺服器,在Stop()方法中停止伺服器。并且這個類依賴于Server類,也就是要滿足它的依賴關系,還需要有一個Server元件。伺服器Server,它需要一個Host和Port:
/// <summary>
/// Author:Terrylee
/// Date:2006年4月28日
/// From:http://terrylee.cnblogs.com
/// </summary>
public class Server
{
private string _host;
private int _port;
public Server(string host,int port)
{
this._host = host;
this._port = port;
}
public void Start()
{
Console.WriteLine("Server {0}:{1} Start
",_host,_port);
Console.ReadLine();
}
public void Stop()
{
Console.WriteLine("Server {0}:{1} Stop
",_host,_port);
Console.ReadLine();
}
}
同時對于這個Server類來說,它需要一個配置檔案:
<!-- From:http://terrylee.cnblogs.com -->
<? xml version="1.0" encoding="utf-8" ?>
< configuration >
< components >
< component id ="server" >
< parameters >
< host > localhost </ host >
< port > 110 </ port >
</ parameters >
</ component >
</ components >
</ configuration >
需要注意的是這個配置檔案跟Startable Facility沒有任何關系,我們在配置檔案中看不到任何和Startable Facility有關的代碼。它隻是一個普通的Castle IOC配置檔案,因為我們在概述中已經說過了,Startable Facility是不需要配置檔案的。好了,現在我們來看客戶程式的使用:
/// <summary>
/// Author:Terrylee
/// Date:2006年4月28日
/// From:http://terrylee.cnblogs.com
/// </summary>
public class App
{
public static void Main()
{
//建立Windsor容器
IWindsorContainer container = new WindsorContainer(new XmlInterpreter("http://www.cnblogs.com/BasicUsage.xml"));
//添加Facility
container.AddFacility("startable", new StartableFacility());
//添加Program元件 (A)
container.AddComponent("program", typeof(Program));
//添加Server元件(B)
container.AddComponent("server", typeof(Server));
}
}
可以看到,在這個過程中,沒有一點多餘的代碼,首先添加Startable Facility到容器中,然後添加Program元件,即執行到上面的A句的時候,因為還沒有添加Server元件,不滿足它的依賴關系,是以它無法啟動,當添加完Server元件後,即執行了B句後,滿足了它的依賴關系,這個它才會自動執行。
三.不實作IStartable接口使用
這是個很多人都忽略的問題,開始時我一直認為隻有實作了IStartable接口才能使用Startable Facility,後來我在讀它的源碼時發現了一個問題,它不僅僅是判斷元件是否實作了這個接口,如果元件有Startable特性也可以在滿足依賴性後 自動啟動,這個在下一篇原理分析篇中我會介紹到。然後我就去查找這方面的資料,很可惜的網上從來沒有介紹這種使用方法,我從它的TestCase找到了一 點下面的代碼,供有興趣的朋友參考一下:
沒有實作IStartable接口的元件:
[Transient]
public class NoInterfaceStartableComponent
{
private bool _Started = false;
private bool _Stopped = false;
public void Start()
{
_Started = true;
}
public void Stop()
{
_Stopped = true;
}
public bool Started
{
get
{ return _Started; }
}
public bool Stopped
{
get
{ return _Stopped; }
}
}
測試代碼:
[Test]
public void TestComponentWithNoInterface()
{
IKernel kernel = new DefaultKernel();
MutableConfiguration compNode = new MutableConfiguration("component");
compNode.Attributes["id"] = "b";
compNode.Attributes["startable"] = "true";
compNode.Attributes["startMethod"] = "Start";
compNode.Attributes["stopMethod"] = "Stop";
kernel.ConfigurationStore.AddComponentConfiguration("b", compNode);
kernel.AddFacility( "startable", new StartableFacility() );
kernel.AddComponent( "b", typeof(NoInterfaceStartableComponent) );
NoInterfaceStartableComponent component = kernel["b"] as NoInterfaceStartableComponent;
Assert.IsNotNull(component);
Assert.IsTrue( component.Started );
Assert.IsFalse( component.Stopped );
kernel.ReleaseComponent(component);
Assert.IsTrue( component.Stopped );
}
對于IKrnel大家可以自行修改為Castle.Windsor,這樣也不失為一種使用Startable Facility的方法。