问题
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