Quartz.NET 5自定义JobFactory注册后无法触发问题求助
问题原因
你在配置Quartz时同时调用了UseJobFactory<JobFactory>()和UseMicrosoftDependencyInjectionJobFactory(),后者是Quartz官方提供的适配.NET依赖注入的默认JobFactory实现,执行顺序靠后的它会覆盖你前面自定义的JobFactory配置,导致自定义逻辑不生效。同时你仅注册了JobFactory本身的实例,Quartz默认会按IJobFactory接口类型从容器中拉取实例,也会导致自定义工厂无法被正确加载。
正确配置步骤
- 移除Quartz配置中的
UseMicrosoftDependencyInjectionJobFactory()调用,避免覆盖自定义JobFactory配置 - 将自定义JobFactory注册为
IJobFactory接口的实现,而不是仅注册自身类型 - 确保你自己实现的所有业务Job类,以及
ILogTime等依赖都已注册到DI容器中
完整注册示例
// 1. 注册业务依赖 services.AddSingleton<ILogTime, 你的LogTime实现类>(); // 注册所有自定义业务Job,按你的需求选Transient/Scoped生命周期 services.AddTransient<你的业务Job类>(); // 2. 注册自定义JobFactory为IJobFactory的实现 services.AddSingleton<IJobFactory, JobFactory>(); // 3. 配置Quartz services.AddQuartz(q => { q.SchedulerId = "MyJob"; q.SchedulerName = "MyJob"; // 仅保留自定义JobFactory的注册 q.UseJobFactory<JobFactory>(); // 这里正常注册你的Job和Trigger即可,示例: q.AddJob<你的业务Job类>(opts => opts.WithIdentity("TestJob")); q.AddTrigger(opts => opts .ForJob("TestJob") .WithIdentity("TestJobTrigger") .WithSimpleSchedule(x => x.WithIntervalInSeconds(10).RepeatForever())); }); services.AddQuartzHostedService(options => { options.WaitForJobsToComplete = true; });
可选优化:适配Scoped生命周期服务
如果你有注册为Scoped生命周期的依赖,直接用根容器解析会出现生命周期不匹配的问题,建议对JobFactory和装饰器做如下修改:
// 修改JobFactory的NewJob方法,创建Scope解析服务 public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { var scope = _container.CreateScope(); var job = (IJob)scope.ServiceProvider.GetRequiredService(bundle.JobDetail.JobType); var logTime = scope.ServiceProvider.GetRequiredService<ILogTime>(); return new JobLogDecorator(job, logTime, scope); } // 给JobLogDecorator增加Scope持有和释放逻辑 public class JobLogDecorator : IJob, IDisposable { private readonly IJob _decorated; private readonly ILogTime _log; private readonly IServiceScope _scope; public JobLogDecorator (IJob decorated, ILogTime log, IServiceScope scope) { _decorated = decorated; _log = log; _scope = scope; } public async Task Execute(IJobExecutionContext context) { var jobName = context.JobDetail.Key.Name; var sw = Stopwatch.StartNew(); await _decorated.Execute(context); _log.Log(sw.ElapsedMilliseconds, jobName); } public void Dispose() { (_decorated as IDisposable)?.Dispose(); _scope.Dispose(); } }
内容的提问来源于stack exchange,提问作者dimmits
相关产品推荐
相关产品推荐

