主要內容
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:
/// </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:
/// </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:-->
<?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:
/// </summary>
public class App
{
public static void Main()
{
//創建Windsor容器
IWindsorContainer container = new WindsorContainer(new XmlInterpreter("../../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的方法。