Quartz.NET 6:IJob的Execute方法未触发,构造函数依赖注入异常
解决Quartz.NET 6跨类库+MVC项目中带依赖注入的Job无法触发问题
核心原因
当Job类带有构造注入时,Quartz默认的Job工厂无法从主项目的DI容器中解析依赖,导致Job实例化失败,进而Execute方法无法触发。单项目场景下DI容器全局可见,所以能正常运行;跨项目时若未正确配置Quartz使用主项目的DI容器,就会出现依赖解析失败的问题。
解决方案步骤
1. 类库中封装服务注册扩展方法
在类库项目中创建扩展类,统一注册Job及依赖服务,方便主项目一键引入:
// 类库中的扩展类 using Microsoft.Extensions.DependencyInjection; using Quartz; namespace YourLibraryNamespace { public static class QuartzJobExtensions { public static IServiceCollection AddQuartzLibraryJobs(this IServiceCollection services) { // 注册Job依赖的业务服务(比如IPublisherService) services.AddScoped<IPublisherService, PublisherServiceImpl>(); // 注册Quartz Job并配置触发器 services.AddQuartz(q => { var jobKey = new JobKey("JobExecuteService"); q.AddJob<JobExecuteService>(opts => opts.WithIdentity(jobKey)); // 示例:配置Cron触发器(可根据需求调整,也可移至主项目配置) q.AddTrigger(opts => opts .ForJob(jobKey) .WithIdentity("JobExecuteServiceTrigger") .WithCronSchedule("0/5 * * * * ?")); }); // 配置Quartz使用Microsoft DI的Job工厂,同时托管Quartz服务 services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true); return services; } } }
2. 主项目中调用类库扩展方法
在MVC项目的Program.cs中,调用类库的扩展方法,确保所有依赖和Job都被注册到主项目的DI容器:
var builder = WebApplication.CreateBuilder(args); // 添加MVC基础服务 builder.Services.AddControllersWithViews(); // 引入类库的Quartz服务配置 builder.Services.AddQuartzLibraryJobs(); var app = builder.Build(); // MVC中间件配置... app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
3. 确保Job类的构造注入合规
Job类的构造函数需正确声明依赖,且依赖的服务已在DI容器中注册:
// 类库中的JobExecuteService using Quartz; using Microsoft.Extensions.Configuration; namespace YourLibraryNamespace { public class JobExecuteService : IJob { private readonly IPublisherService _publisherService; private readonly IConfiguration _configuration; // 构造注入依赖服务 public JobExecuteService(IPublisherService publisherService, IConfiguration configuration) { _publisherService = publisherService; _configuration = configuration; } public async Task Execute(IJobExecutionContext context) { // 执行业务逻辑 await _publisherService.PublishAsync("定时任务触发"); var appSetting = _configuration["AppSettings:TargetKey"]; // ...其他业务代码 } } }
关键注意事项
- 强制配置Microsoft DI Job工厂:如果主项目单独配置Quartz,必须添加
q.UseMicrosoftDependencyInjectionJobFactory();,否则Quartz会使用自身容器,无法解析主项目DI中的依赖。 - Job类必须为public:Quartz需要反射实例化Job类,非public访问修饰符会导致实例化失败。
- 开启日志排查:在
appsettings.json中配置Quartz日志级别为Information,可查看Job调度状态、实例化错误等信息:"Logging": { "LogLevel": { "Quartz": "Information" } } - 避免无参构造冲突:不要同时保留无参构造函数,否则Quartz会优先使用无参构造,导致依赖无法注入。
内容的提问来源于stack exchange,提问作者Batu han
相关产品推荐
相关产品推荐

