c# .NET MVC 4 - 如何创建使用 Ninject 服务的 Quartz 作业?

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

我正在使用 .NET MVC 4。所有服务都是使用 Ninject 注入的。我正在尝试使用 Quartz 安排工作。目前,Global.asax 中的招聘信息如下:

Global.asax:

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

    ScheduledJobs.RegisterJobs();
}

ScheduleJobs.csScheduledJobs class,它创建带触发器的作业并将它们添加到标准计划。

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

这是职位代码:

public class JobUsingService : IJobUsingService, IJob {

   private ISomeService someService;

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

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

问题是 JobUsingService 必须使用 Ninject 初始化,以便将 SomeService 注入其中(也通过 Ninject)。调用 IJobDetail job = JobBuilder.Create<JobUsingService>().WithIdentity("JobUsingService").Build(); 会跳过 Ninject 注入并创建 class 的常规实例而不注入必要的服务。

如何使用 Ninject 创建 JobUsingService 类型的工作?

This SO answer建议创建一个NinjectJobFactory,但我不确定如何实际使用这个工厂并创造就业机会。

是的,您必须使用 referenced answerNinjectJobFactory。在应用程序初始化例程中(Application_Start 或任何您配置应用程序使用 ninject 的地方。在内核创建之后)您必须执行:

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

或者:

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

(无所谓,它们完全可以互换)

从那时起,Quarty 将创建作业类型(JobUsingService 使用 NinjectJobFactory,后者又使用 kernel 创建作业...

最后,我们需要添加 this SO answer

中描述的 NinjectJobFactory class

我们还必须进行以下更改:

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