Startable Facility 讓組件在依賴關係滿足後自動啟動/停止。資訊:
| 屬性 | 值 |
|---|---|
| Uses Proxy | No |
| Requires Configuration | No |
| Uses Attributes | No |
| Version | Beta 2 |
public class Program : IStartable
{
private Server _server;
public Program(Server server) { this._server = server; }
public void Start() { _server.Start(); }
public void Stop() { _server.Stop(); }
}
public class Server
{
private string _host; private int _port;
public Server(string host, int port) { _host = host; _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(); }
}
<?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 無關,純屬 Castle IOC 普通配置。
public class App
{
public static void Main()
{
IWindsorContainer container = new WindsorContainer(new XmlInterpreter("../../BasicUsage.xml"));
container.AddFacility("startable", new StartableFacility());
container.AddComponent("program", typeof(Program)); // (A) 依賴未滿足,不啟動
container.AddComponent("server", typeof(Server)); // (B) 依賴滿足,自動啟動
}
}
執行到 (A) 時 Server 尚未註冊,依賴不滿足;執行 (B) 後依賴滿足,Program 自動啟動呼叫 Start()。
源碼揭示:除介面判斷外,若組件有 startable Attribute 也可自動啟動。
[Transient]
public class NoInterfaceStartableComponent
{
private bool _Started = false, _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));
var component = kernel["b"] as NoInterfaceStartableComponent;
Assert.IsNotNull(component);
Assert.IsTrue(component.Started);
Assert.IsFalse(component.Stopped);
kernel.ReleaseComponent(component);
Assert.IsTrue(component.Stopped);
}
可將 IKernel 換為 Castle.Windsor 使用。這提供了不實作介面也能享受自動生命週期管理的彈性。