c# .NET MVC 4 - How do I create Quartz jobs that u

2019-08-06 01:06发布

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.

2条回答
贼婆χ
2楼-- · 2019-08-06 01:31

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...

查看更多
太酷不给撩
3楼-- · 2019-08-06 01:50

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);
    }
}
查看更多
登录 后发表回答