Quartz.Netdependency injection.Net核心

在我的项目中,我必须使用Quartz,但我不知道我做错了什么。

的JobFactory:

public class IoCJobFactory : IJobFactory { private readonly IServiceProvider _factory; public IoCJobFactory(IServiceProvider factory) { _factory = factory; } public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { return _factory.GetService(bundle.JobDetail.JobType) as IJob; } public void ReturnJob(IJob job) { var disposable = job as IDisposable; if (disposable != null) { disposable.Dispose(); } } } 

QuartzExtensions:

 public static class QuartzExtensions { public static void UseQuartz(this IApplicationBuilder app) { app.ApplicationServices.GetService(); } public static async void AddQuartz(this IServiceCollection services) { var props = new NameValueCollection { {"quartz.serializer.type", "json"} }; var factory = new StdSchedulerFactory(props); var scheduler = await factory.GetScheduler(); var jobFactory = new IoCJobFactory(services.BuildServiceProvider()); scheduler.JobFactory = jobFactory; await scheduler.Start(); services.AddSingleton(scheduler); } } 

当我尝试运行我的Job(类有dependency injection)时,我总是得到Exception因为:

 _factory.GetService(bundle.JobDetail.JobType) as IJob; 

永远是空的。

我的类实现IJob并在startup.cs中添加:

 services.AddScoped(); services.AddQuartz(); 

 app.UseQuartz(); 

我使用标准的.net核心dependency injection:

 using Microsoft.Extensions.DependencyInjection; 

这就是我在我的应用程序中的做法。 而不是将调度程序添加到ioc我只添加工厂

 services.AddTransient( (provider) => { return new AspJobFactory( provider ); } ); 

我的工作工作看起来几乎一样。 瞬态并不重要,因为我只使用过一次。 我用的是Quartz扩展方法

 public static void UseQuartz(this IApplicationBuilder app, Action configuration) { // Job Factory through IOC container var jobFactory = (IJobFactory)app.ApplicationServices.GetService( typeof( IJobFactory ) ); // Set job factory Quartz.Instance.UseJobFactory( jobFactory ); // Run configuration configuration.Invoke( Quartz.Instance ); // Run Quartz Quartz.Start(); } 

Quartz类也是Singleton。

这只是解决IoC问题的解决方案的一个简单示例:

JobFactory.cs

 public class JobFactory : IJobFactory { protected readonly IServiceProvider Container; public JobFactory(IServiceProvider container) { Container = container; } public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { return Container.GetService(bundle.JobDetail.JobType) as IJob; } public void ReturnJob(IJob job) { (job as IDisposable)?.Dispose(); } } 

Startup.cs

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime lifetime, IServiceProvider container) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseMvc(); // the following 3 lines hook QuartzStartup into web host lifecycle var quartz = new QuartzStartup(container); lifetime.ApplicationStarted.Register(quartz.Start); lifetime.ApplicationStopping.Register(quartz.Stop); } 

QuartzStartup.cs

 public class QuartzStartup { private IScheduler _scheduler; // after Start, and until shutdown completes, references the scheduler object private readonly IServiceProvider container; public QuartzStartup(IServiceProvider container) { this.container = container; } // starts the scheduler, defines the jobs and the triggers public void Start() { if (_scheduler != null) { throw new InvalidOperationException("Already started."); } var schedulerFactory = new StdSchedulerFactory(); _scheduler = schedulerFactory.GetScheduler().Result; _scheduler.JobFactory = new JobFactory(container); _scheduler.Start().Wait(); var voteJob = JobBuilder.Create() .Build(); var voteJobTrigger = TriggerBuilder.Create() .StartNow() .WithSimpleSchedule(s => s .WithIntervalInSeconds(60) .RepeatForever()) .Build(); _scheduler.ScheduleJob(voteJob, voteJobTrigger).Wait(); } // initiates shutdown of the scheduler, and waits until jobs exit gracefully (within allotted timeout) public void Stop() { if (_scheduler == null) { return; } // give running jobs 30 sec (for example) to stop gracefully if (_scheduler.Shutdown(waitForJobsToComplete: true).Wait(30000)) { _scheduler = null; } else { // jobs didn't exit in timely fashion - log a warning... } } } 

考虑您应该提前将服务注册到容器中(在我的案例中为VoteJob)。
我根据这个答案实现了这一点。
我希望它能有所帮助。

我遇到了同样的问题。

我来自更新

services.AddScoped();

services.AddScoped();

然后它工作。

_factory.GetService(bundle.JobDetail.JobType) as IJob; 不会是空的:)