2011-09-12 33 views
6

क्या डीई कंटेनर एकता द्वारा इंजेक्शन किए गए उदाहरण IJob उदाहरण का हमेशा उपयोग करने के लिए क्वार्ट्ज नौकरी पंजीकृत करना संभव है? मैं एक वर्ग Monitor एकता डि से आ रही का एक उदाहरण "मॉनिटर" है, जो मैं पंजीकृत के रूप में:क्वार्ट्ज, एकता और .NET

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

:

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

और मेरे IJob कार्यान्वयन की निगरानी उदाहरण यह में इंजेक्शन की अपेक्षा करता है लेकिन जब क्वार्ट्ज घटनाएं आग लगती हैं, तो IJob.Execute() कार्यान्वयन को इंजेक्शन मिलने से पहले बुलाया जाता है। मुझे यह कैसे काम करना चाहिए? क्या मुझे इसके बजाय अन्य डी कंटेनर या शेड्यूलर पर विचार करना चाहिए?

धन्यवाद

उत्तर

5

क्वार्ट्ज हर आग घटना पर काम इंटरफेस कार्यान्वयन reinstantiate होगा।

IStatefulJob उदाहरणों नियमित IJob उदाहरणों से थोड़ा अलग नियमों का पालन करें: यह recommendedIStatefulJob उपयोग करने के लिए अगर आप काम फांसी के बीच राज्य की रक्षा करना चाहते हैं। मुख्य अंतर यह है कि उनके संबंधित जॉबडाटा मैप नौकरी के प्रत्येक निष्पादन के बाद फिर से जारी रहता है, इस प्रकार अगले निष्पादन के लिए स्थिति को संरक्षित करता है। दूसरा अंतर यह है कि राज्यव्यापी नौकरियों को समवर्ती निष्पादित करने की अनुमति नहीं है, जिसका अर्थ है कि नए ट्रिगर जो IJob.Execute विधि को पूरा करने से पहले होता है देरी होगी।

क्वार्ट्ज tutorial से

:

StatefulJob

अब, एक नौकरी की राज्य डेटा (उर्फ JobDataMap) के बारे में कुछ अतिरिक्त नोट्स: एक नौकरी उदाहरण के रूप में "स्टेटफुल" या "गैर परिभाषित किया जा सकता -stateful "। गैर-स्टेटफुल जॉब्स में केवल शेड्यूलर में जोड़े जाने पर ही उनके जॉबडेटा मैप को संग्रहीत किया जाता है। इसका मतलब है कि नौकरी के निष्पादन के दौरान नौकरी डेटा मानचित्र की सामग्री में कोई भी परिवर्तन खो जाएगा, और अगली बार इसे निष्पादित करने पर नौकरी से नहीं देखा जाएगा। आपके पास शायद अनुमान लगाया गया है, एक राज्यव्यापी नौकरी सिर्फ विपरीत है - नौकरी के हर निष्पादन के बाद उसका जॉबडाटा मैप पुनः संग्रहीत है। का एक दुष्प्रभाव नौकरी को प्रमाणित करने का एक पक्ष प्रभाव यह है कि इसे समवर्ती रूप से निष्पादित नहीं किया जा सकता है। या दूसरे शब्दों में: यदि कोई नौकरी राज्यव्यापी है, और एक ट्रिगर को पहले से निष्पादित करते समय नौकरी 'आग' करने का प्रयास करता है, तो ट्रिगर पिछले निष्पादन पूर्ण होने तक अवरुद्ध करेगा (प्रतीक्षा करें)।

जॉब इंटरफ़ेस की बजाय आप स्टेटफुल जोब इंटरफ़ेस को कार्यान्वित करके एक नौकरी को राज्य के रूप में चिह्नित करें।

आप के लिए एक अन्य विकल्प अपने स्वयं के JobFactory लागू करने के लिए है:

नौकरी 'उदाहरण'

इस विषय पर एक अंतिम बात यह है कि या नहीं अब तक स्पष्ट हो सकता है हो सकता है: आप कर सकते हैं जॉब डिस्प्ले के कई उदाहरण बनाकर शेड्यूलर के भीतर कई 'इंस्टेंस परिभाषाओं' को संग्रहित करें - प्रत्येक के अपने गुणों और जॉबडाटामैप - के साथ और उन्हें सभी शेड्यूलर में जोड़कर।

जब कोई ट्रिगर आग लगती है, तो जॉब इसे शेड्यूलर पर कॉन्फ़िगर किया गया जॉबफ़ैक्टरी के माध्यम से तत्काल किया जाता है। डिफ़ॉल्ट जॉबफ़ैक्टरी बस जॉब क्लास पर newInstance() को कॉल करता है। आप जैसी चीजों को पूरा करने के लिए को अपने आवेदन के आईओसी या डी कंटेनर उत्पाद/ नौकरी के उदाहरण को प्रारंभ करने के लिए अपने स्वयं के कार्यान्वयन को बनाना चाहते हैं।

+0

ठीक है, मैं एक ही IJob उदाहरण पकड़े में कोई दिलचस्पी नहीं हूँ, क्या मैं चाहता हूँ एक ही IMonitor प्रत्येक नए IJob उदाहरण में इंजेक्ट किया है करने के लिए है ... – j040p3d20

+2

स्टोर अपने JobDataMap में 'मॉनिटर' के संदर्भ में या अपने स्वयं के जॉब फैक्टरी को लागू करें। – Dmitry

+0

'स्टेटफुल जोब' इंटरफेस को बहिष्कृत कर दिया गया है ... यह एनोटेशन का उपयोग करने की सिफारिश करता है http://quartz-scheduler.org/documentation/quartz-2.x/new-in-quartz-2 – Jaider

2

आप अपना खुद का जॉबफैक्टरी लागू करके ऐसा कर सकते हैं।

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 गुण सेट: आप IJobFactory इंटरफ़ेस को लागू करना होगा।

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; 
     } 
    } 
} 

दिलचस्प लाइन है:

संदर्भ के लिए, डिफ़ॉल्ट काम कारखाने कि quartz.net का उपयोग करता है

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 को ओवरराइड करता है और नौकरी कक्षाओं को तुरंत चालू करने के लिए वसंत का उपयोग करता है।

/// <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) 
    { 
    } 
}