c# .NET MVC 4 - How do I create Quartz jobs that use Ninject services?

六眼飞鱼酱① 提交于 2019-12-11 08:33:50

问题


I am using .NET MVC 4. All services are injected using Ninject. I am trying to schedule a job using Quartz. Right now, jobs are registered in Global.asax as follows:

Global.asax:

protected void Application_Start() {
    // ... configuration stuff

    ScheduledJobs.RegisterJobs();
}

ScheduleJobs.cs has the ScheduledJobs class, which creates jobs with triggers and adds them to a standard schedule.

In ScheduleJobs.cs:

public class ScheduledJobs {

  public static void RegisterJobs() {
    IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();

    scheduler.Start();

    IJobDetail job = JobBuilder.Create<JobUsingService>()
        .WithIdentity("JobUsingService")
        .Build();

    ITrigger trigger = TriggerBuilder.Create()
        .WithDailyTimeIntervalSchedule(s =>
            s.WithIntervalInHours(1)
            .OnEveryDay()
            .StartingDailyAt(new Quartz.TimeOfDay(DateTime.Now.Hour, DateTime.Now.Minute)))
        .Build();

    scheduler.ScheduleJob(job, trigger);
  }
}

This is the job code:

public class JobUsingService : IJobUsingService, IJob {

   private ISomeService someService;

   public JobUsingService(ISomeService _someService) {
       someService = _someService;
   }

   public void Execute(IJobExecutionContext context) {
       someService.someStuff();
   }
}

The problem is that JobUsingService has to be initialized using Ninject so that SomeService is injected into it (also by Ninject). Calling IJobDetail job = JobBuilder.Create<JobUsingService>().WithIdentity("JobUsingService").Build(); skips over the Ninject injection and creates a regular instance of the class without injecting the necessary services.

How can I create a job of type JobUsingService using Ninject?

This SO answer suggests creating a NinjectJobFactory, but I am not sure how to actually use this factory and create jobs.


回答1:


Yes you'll have to use the NinjectJobFactory of the referenced answer. In an app initialization routine (Application_Start or wherever you configure the application to use ninject. Just after the creation of the kernel) you have to do:

Quartz.IScheduler.JobFactory = kernel.Get<NinjectJobFactory>();

or alternatively:

Quartz.IScheduler.JobFactory = new NinjectJobFactory(kernel);

(doesn't matter which, they're completely interchangeable)

From then on Quarty will create the job types (JobUsingService using the NinjectJobFactory which in turns uses the kernel to create the jobs...




回答2:


In the end, we needed to add the NinjectJobFactory class described in this SO answer

We also had to make the following changes:

In ScheduleJobs.cs:

public class ScheduledJobs {

    public static void RegisterJobs() {
        // Create a new kernel and create the necessary bindings
        IKernel kernel = new StandardKernel();
        kernel.Bind<IJobUsingService>().To<JobUsingService>();

        // Create a scheduler and give it the Ninject job factory created earlier
        IScheduler scheduler = new StdSchedulerFactory().GetScheduler();
        scheduler.JobFactory = new NinjectJobFactory(kernel);

        // Create the job with the interface which will be injected
        IJobDetail job = JobBuilder.Create<IJobUsingService>()
             .WithIdentity("IJobUsingService")
             .Build();

         // Create the trigger
         ITrigger trigger = TriggerBuilder.Create()
             .WithDailyTimeIntervalSchedule(s =>
                 s.WithIntervalInHours(23)
                  .OnEveryDay()
                  .StartingDailyAt(new Quartz.TimeOfDay(DateTime.Now.Hour, DateTime.Now.Minute)))
             .Build();

         scheduler.ScheduleJob(job, trigger);
    }
}


来源:https://stackoverflow.com/questions/28369444/c-sharp-net-mvc-4-how-do-i-create-quartz-jobs-that-use-ninject-services

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!