In my current project we need to use Quartz .NET for scheduled tasks. Since we already use Unity IoC it makes sense to inject all dependencies into quartz jobs. After googling I found this repository but example in that soulution as well as the nuget package keep throwing exceptions. Turned out to be that in order to integrate any IoC container with quartz it's enough to do three simple steps.
1. Implement IJobFactory interface
2. Inherit StdSchedulerFactory
3. Register those two implementations in the container
In adition to keep everything more separated, independat and easier to use, we can extract registration into a Unity extension.
And of cause an example.
1. Implement IJobFactory interface
public class UnityJobFactory : IJobFactory { private readonly IUnityContainer _container; public UnityJobFactory(IUnityContainer container) { _container = container; } public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { return _container.Resolve(bundle.JobDetail.JobType) as IJob; } public void ReturnJob(IJob job) { } }
2. Inherit StdSchedulerFactory
public class UnitySchedulerFactory : StdSchedulerFactory { private readonly IJobFactory _jobFactory; public UnitySchedulerFactory(IJobFactory jobFactory) { _jobFactory = jobFactory; } protected override IScheduler Instantiate(QuartzSchedulerResources rsrcs, QuartzScheduler qs) { qs.JobFactory = _jobFactory; return base.Instantiate(rsrcs, qs); } }
3. Register those two implementations in the container
container.RegisterType<IJobFactory, UnityJobFactory>(); container.RegisterType<ISchedulerFactory, UnitySchedulerFactory>();
In adition to keep everything more separated, independat and easier to use, we can extract registration into a Unity extension.
public class QuartzUnityExtension : UnityContainerExtension { protected override void Initialize() { this.Container.RegisterType<IJobFactory, UnityJobFactory>(); this.Container.RegisterType<ISchedulerFactory, UnitySchedulerFactory>(); } }
And of cause an example.
public class MyJob : IJob { private readonly ISomeService _someService; public MyJob(ISomeService someService) { _someService = someService; } public void Execute(IJobExecutionContext context) { Console.WriteLine(_someService.GiveMeSomething()); } } public interface ISomeService { string GiveMeSomething(); } public class SomeService : ISomeService { public string GiveMeSomething() { return "Something"; } } public class Program { public static void Main(string[] args) { var container = new UnityContainer(); container.AddNewExtension<QuartzUnityExtension>(); container.RegisterType<ISomeService, SomeService>(); var scheduler = container.Resolve<ISchedulerFactory>().GetScheduler(); scheduler.ScheduleJob( new JobDetailImpl("myJob", typeof(MyJob)), new CalendarIntervalTriggerImpl("TestTrigger", IntervalUnit.Second, 2) ); scheduler.Start(); Thread.Sleep(TimeSpan.FromSeconds(10)); scheduler.Shutdown(); } }