2011-09-12 35 views
6

是否可以註冊一個石英作業來始終使用DI容器Unity注入的相同實例IJob?我從團結DI未來一類Monitor的單個實例「監控」,至極我註冊爲:Quartz,Unity&.NET

container.RegisterType<IMonitor, Monitor>(new ContainerControlledLifetimeManager()) 

和我IJob實施預計將有注入它是顯示器的實例:

class MyJob : IJob { 
... 
[Dependency] IMonitor monitor {get; set;} 
... 
void Execute() 
... 
} 

但是當石英事件觸發時,在注入依賴關係之前調用IJob.Execute()實現。我應該如何得到這個工作?我應該考慮其他DI容器還是調度器?

感謝

回答

5

石英將在重新實例每隔火災事件的工作接口的實現。這是recommended使用IStatefulJob如果你想工作執行之間保持狀態:

IStatefulJob情況下,遵循規律 IJob情況稍有不同的規則。關鍵的區別在於,在每次執行作業之後,它們的關聯的JobDataMap 將被重新保留,從而爲下一次執行保留 狀態。另一個區別是,有狀態的 作業不允許同時執行,這意味着在IJob.Execute方法完成之前發生的新觸發器 將延遲 。

石英tutorial

StatefulJob

現在,關於作業的狀態數據(又名JobDataMap的)一些其他注意事項: 任務實例可以被定義爲 「全狀態」 或「非-stateful」。 非有狀態作業只有在他們的 被添加到調度程序時才存儲它們的JobDataMap。這意味着在作業執行期間對作業數據映射的內容所作的任何更改都將丟失, 將在下次執行作業時看不到。你可能猜到了 ,有狀態的工作恰恰相反 - 它的JobDataMap 在每次作業執行後都會被重新存儲。 使工作有狀態的一個副作用是它不能同時執行。換句話說,如果一個作業是有狀態的,並且一個觸發器在該作業已經執行時試圖'觸發'該作業,則該觸發器將阻塞(等待) ,直到上一次執行完成爲止。

通過讓Job實現StatefulJob 接口而不是Job接口,可以將Job標記爲有狀態。

你的另一個選擇是實現自己的JobFactory:

工作「實例」

有關這個主題的最後一個點,可能會或可能不會很明顯現在: 可以創建一個作業班,並通過創建多個實例JobDetails的 調度中存儲了很多「實例 定義」 - 每一個都有自己的屬性和JobDataMap中的 - 和他們都增加了調度。

當觸發器觸發時,它所關聯的作業通過 實例化在Scheduler上配置的JobFactory。默認的JobFactory 只需在作業類調用的newInstance()。 您可能希望創建自己的JobFactory實現,以完成諸如 之類的操作,從而讓您的應用程序的IoC或DI容器生成/初始化 作業實例

+0

嗯,我不感興趣,持有到同一IJob情況下,我要的是具有相同的iMonitor注入到每一個新的IJob實例... – j040p3d20

+2

存儲參考您在JobDataMap的「監視」或實現自己的JobFactory。 – Dmitry

+0

的'StatefulJob'接口已被棄用...它建議使用註釋http://quartz-scheduler.org/documentation/quartz-2.x/new-in-quartz-2 – Jaider

2

您可以通過實現自己的JobFactory做到這一點。你必須實現IJobFactory接口:

public interface IJobFactory 
{ 
    /// <summary> 
    /// Called by the scheduler at the time of the trigger firing, in order to 
    /// produce a <see cref="IJob" /> instance on which to call Execute. 
    /// </summary> 
    /// <remarks> 
    /// <p> 
    /// It should be extremely rare for this method to throw an exception - 
    /// basically only the the case where there is no way at all to instantiate 
    /// and prepare the Job for execution. When the exception is thrown, the 
    /// Scheduler will move all triggers associated with the Job into the 
    /// <see cref="TriggerState.Error" /> state, which will require human 
    /// intervention (e.g. an application restart after fixing whatever 
    /// configuration problem led to the issue wih instantiating the Job. 
    /// </p> 
    /// 
/// </remarks> 
    /// <param name="bundle"> 
    /// The TriggerFiredBundle from which the <see cref="JobDetail" /> 
    /// and other info relating to the trigger firing can be obtained. 
    /// </param> 
    /// <throws> SchedulerException if there is a problem instantiating the Job. </throws> 
    /// <returns> the newly instantiated Job 
    /// </returns> 
    IJob NewJob(TriggerFiredBundle bundle); 
} 

然後,調度的quartz.scheduler.jobFactory.type屬性設置爲你的工作工廠的類型。

僅供參考,下面是quartz.net使用默認作業工廠:

public class SimpleJobFactory : IJobFactory 
{ 
    private static readonly ILog Log = LogManager.GetLogger(typeof (SimpleJobFactory)); 

    /// <summary> 
    /// Called by the scheduler at the time of the trigger firing, in order to 
    /// produce a <see cref="IJob" /> instance on which to call Execute. 
    /// </summary> 
    /// <remarks> 
    /// It should be extremely rare for this method to throw an exception - 
    /// basically only the the case where there is no way at all to instantiate 
    /// and prepare the Job for execution. When the exception is thrown, the 
    /// Scheduler will move all triggers associated with the Job into the 
    /// <see cref="TriggerState.Error" /> state, which will require human 
    /// intervention (e.g. an application restart after fixing whatever 
    /// configuration problem led to the issue wih instantiating the Job. 
/// </remarks> 
    /// <param name="bundle">The TriggerFiredBundle from which the <see cref="JobDetail" /> 
    /// and other info relating to the trigger firing can be obtained.</param> 
    /// <returns>the newly instantiated Job</returns> 
    /// <throws> SchedulerException if there is a problem instantiating the Job. </throws> 
    public virtual IJob NewJob(TriggerFiredBundle bundle) 
    { 
     JobDetail jobDetail = bundle.JobDetail; 
     Type jobType = jobDetail.JobType; 
     try 
     { 
      if (Log.IsDebugEnabled) 
      { 
       Log.Debug(string.Format(CultureInfo.InvariantCulture, "Producing instance of Job '{0}', class={1}", jobDetail.FullName, jobType.FullName)); 
      } 

      return (IJob) ObjectUtils.InstantiateType(jobType); 
     } 
     catch (Exception e) 
     { 
      SchedulerException se = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Problem instantiating class '{0}'", jobDetail.JobType.FullName), e); 
      throw se; 
     } 
    } 
} 

有趣的路線是:

return (IJob) ObjectUtils.InstantiateType(jobType); 
5

看一看Quartz.Unity。

https://www.nuget.org/packages/Quartz.Unity/1.0.1

文檔是很稀疏,但現在看來,所有你需要做的就是添加的NuGet包和下面一行到您的容器配置。

var container = new UnityContainer().AddNewExtension<Quartz.Unity.QuartzUnityExtension>(); 
0

創建一個覆蓋SimpleJobFactory並使用spring來實例化作業類的CustomJobfactory。

/// <summary> 
/// Custom Job Factory 
/// </summary> 
public class CustomJobFactory : SimpleJobFactory 
{ 
    /// <summary> 
    /// Application context 
    /// </summary> 
    private IApplicationContext context; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="CustomJobFactory" /> class. 
    /// </summary> 
    public CustomJobFactory() 
    { 
     this.context = ContextRegistry.GetContext(); 
    } 

    /// <summary> 
    /// Creates a new job instance 
    /// </summary> 
    /// <param name="bundle">Trigger bundle</param> 
    /// <param name="scheduler">Job scheduler</param> 
    /// <returns></returns> 
    public override IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) 
    { 
     IJobDetail jobDetail = bundle.JobDetail; 
     Type jobType = jobDetail.JobType; 
     return this.context.GetObject(jobType.Name) as IJob; 
    } 

    /// <summary> 
    /// Return job 
    /// </summary> 
    /// <param name="job">Job instance</param> 
    public override void ReturnJob(IJob job) 
    { 
    } 
}