Castle是針對.NET平臺的一個開源項目,從數據訪問框架ORM到IOC容器,再到WEB層的MVC框架、AOP,基本包括了整個開發過程中的所有東西,爲我們快速的構建企業級的應用程序提供了很好的服務.具體可參看TerryLee的Castle 開發系列文章。
可以通過稱爲 Facility 的組件用控制反轉 (Inversion of Control, IoC) 和依賴注入將 第三方組件插入內核中。Startable Facility當一個組件滿足一定的依賴關係之後,讓它自動運行,比如說啓動一個窗體或者啓動某種服務。 Startable Facility的使用可以說是非常地簡單,只要我們的組件實現了IStartable接口就可以了,關於Startable Facility具體可參看Castle IOC容器實踐之Startable Facility(一)、Castle IOC容器實踐之Startable Facility(二)。Quartz 是一個要與 Castle集成的大項目,因爲它僅需要您用 Castle的生命週期來啓動和停止它。這意味着,當 Castle啓動時,您想要 Quartz 啓動,當 Castle關閉時,您想要 Quartz 停止。
爲了保持本示例的簡單性,Quartz 配置使用 Quartz 發行版附帶的默認值。這些默認值位於 quartz.properties 文件中,該文件是 dll 文件的一部分。要配置 Quartz 以將數據庫用於持久層、遠程調度和其他高級選項,必須創建自定義的 quartz.properties 文件。
Quartz 調度器易於啓動和關閉;它只通過調用 StdSchedulerFactory.DefaultScheduler 來檢索調度器對象。要啓動 Quartz,執行 Scheduler.Start() 方法。要停止 Quartz,執行 Scheduler.Shutdown() 方法。要使 Quartz 的生命週期跟隨 Castle,將 Start() 調用放入 IStartable的 Start() 方法中,並將 Shutdown() 調用放入 IStartable的 Stop() 方法中。清單 3 展示了添加 Quartz 代碼之後完整的實現。
1: using Castle.Core;
2: using Quartz.Impl;
3: using Quartz;
4: using Common.Logging;
5: using System.Threading;
6:
7: namespace QuartzComponent
8: {
9: [Transient]
10: public class QuartzStartable : IStartable
11: {
12: private ISchedulerFactory _schedFactory;
13:
14: private static ILog log = LogManager.GetLogger(typeof(QuartzStartable));
15:
16: public QuartzStartable(ISchedulerFactory schedFactory)
17: {
18: _schedFactory = schedFactory;
19: }
20:
21: public void Start()
22: {
23: log.Info("Starting service");
24: IScheduler sched = _schedFactory.GetScheduler();
25:
26: log.Info("------- Scheduling Jobs ----------------");
27:
28: // jobs can be scheduled before sched.start() has been called
29:
30: // get a "nice round" time a few seconds in the future...
31: DateTime ts = TriggerUtils.GetNextGivenSecondDate(null, 15);
32:
33: // job1 will only fire once at date/time "ts"
34: JobDetail job = new JobDetail("job1", "group1", typeof(SimpleQuartzJob));
35: SimpleTrigger trigger = new SimpleTrigger("trigger1", "group1");
36: // set its start up time
37: trigger.StartTime = ts;
38: // set the interval, how often the job should run (10 seconds here)
39: trigger.RepeatInterval = 10000;
40: // set the number of execution of this job, set to 10 times.
41: // It will run 10 time and exhaust.
42: trigger.RepeatCount = 100;
43:
44:
45: // schedule it to run!
46: DateTime ft = sched.ScheduleJob(job, trigger);
47: log.Info(string.Format("{0} will run at: {1} and repeat: {2} times, every {3} seconds",
48: job.FullName, ft.ToString("r"), trigger.RepeatCount, (trigger.RepeatInterval / 1000)));
49: log.Info("------- Waiting five minutes... ------------");
50:
51: sched.Start();
52: try
53: {
54: // wait five minutes to show jobs
55: Thread.Sleep(300 * 1000);
56: // executing...
57: }
58: catch (ThreadInterruptedException)
59: {
60: }
61:
62:
63: }
64:
65: public void Stop()
66: {
67: log.Info("Stopping service");
68: try
69: {
70: IScheduler scheduler = _schedFactory.GetScheduler();
71: scheduler.Shutdown(true);
72: }
73: catch (SchedulerException se)
74: {
75: log.Error("Cannot shutdown scheduler.", se);
76: }
77:
78: }
79: }
80: }
將Quartz.net集成到Castle容器中,只需要幾行代碼就可以了,就會在Castle容器啓動的時候自動啓用Quartz.net的作業調度。
1: namespace QuartzComponent
2: {
3: class ConsoleMain
4: {
5: static ILog log = LogManager.GetLogger(typeof(ConsoleMain));
6:
7: [STAThread]
8: public static void Main(string[] args)
9: {
10: IWindsorContainer container = new WindsorContainer();
11: //添加Facility
12:
13: container.AddFacility("startable", new StartableFacility());
14:
15: container.AddComponent("Scheduler", typeof(ISchedulerFactory), typeof(StdSchedulerFactory));
16:
17: container.AddComponent("QuartzStartable", typeof(QuartzStartable));
18:
19: //Console.Read();
20: }
21: }
22: }
結束語
對於大多數開源項目,實現少量工作就可以集成到Castle容器中,類似 Quartz.net 的應用程序是簡單集成的優秀候選項,因爲它只需要啓動和關閉。有很多與 Quartz.net 一樣簡單的有助於集成的開源項目。
下載例子代碼: QuartzComponent.zip