.NET6集成Quartzmon时Quartz作业无法注入已注册服务求助
问题分析与解决方案
你的核心问题是手动创建的Quartz Scheduler没有集成.NET依赖注入容器,导致Quartz无法解析带构造参数的作业,也无法注入已注册的服务。以下是具体修复步骤:
修复方案一:使用Quartz官方.NET集成包(推荐)
直接借助Quartz的.NET集成能力,让Quartz与DI容器深度绑定,无需手动管理Scheduler生命周期:
修改后的Program.cs
var builder = WebApplication.CreateBuilder(args); // 注册自定义仓储服务 builder.Services.AddSingleton<IRepository, Repository>(); // 配置Quartz并集成DI builder.Services.AddQuartz(q => { // 注册作业,允许DI解析构造参数 q.AddJob<RepoJob>(j => j.WithIdentity("RepoJob")); // 配置触发器关联作业 q.AddTrigger(t => t .WithIdentity("RepoJobTrigger") .ForJob("RepoJob") .StartNow() .WithSimpleSchedule(s => s.WithIntervalInMinutes(5).RepeatForever())); // 启用.NET DI作为Quartz的作业工厂,自动注入依赖 q.UseMicrosoftDependencyInjectionJobFactory(); }); // 添加Quartz托管服务,自动管理Scheduler的启动/关闭 builder.Services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true); // 注册Quartzmon builder.Services.AddQuartzmon(); var app = builder.Build(); // 从DI容器获取Scheduler实例给Quartzmon使用 app.UseQuartzmon(new QuartzmonOptions() { Scheduler = app.Services.GetRequiredService<IScheduler>(), VirtualPathRoot = "/Quartzmon", UseLocalTime = true }); await app.RunAsync();
移除冗余代码
删除原来的静态Scheduler类,因为Quartz托管服务会自动完成Scheduler的创建、启动和调度逻辑。
修复方案二:手动改造Scheduler以支持DI(适合需自定义Scheduler逻辑的场景)
如果必须保留手动创建Scheduler的逻辑,需为Scheduler配置DI作业工厂:
修改Scheduler类
public static class Scheduler { // 接收DI服务提供者作为参数 public static async Task<IScheduler> Create(IServiceProvider serviceProvider) { var schedulerFactory = new StdSchedulerFactory(); var scheduler = await schedulerFactory.GetScheduler(); // 替换Quartz默认作业工厂为.NET DI工厂,支持依赖注入 scheduler.JobFactory = new MicrosoftDependencyInjectionJobFactory( serviceProvider.GetRequiredService<IServiceScopeFactory>() ); var job = JobBuilder.Create<RepoJob>().StoreDurably().Build(); var trigger = TriggerBuilder.Create().StartNow().WithSimpleSchedule(sc => sc.WithIntervalInMinutes(5)).Build(); await scheduler.ScheduleJob(job, trigger); await scheduler.Start(); return scheduler; } }
修改Program.cs中的Scheduler调用
var buildConfig = Host.CreateDefaultBuilder(); buildConfig.ConfigureWebHostDefaults(config => { config.ConfigureServices(service => { service.AddSingleton<IRepository, Repository>(); service.AddQuartzmon(); }); config.Configure(app => { // 传入DI服务提供者创建Scheduler var scheduler = Scheduler.Create(app.Services).Result; app.UseQuartzmon(new QuartzmonOptions() { Scheduler = scheduler, VirtualPathRoot = "/Quartzmon", UseLocalTime = true }); }); }); var builder = buildConfig.Build(); await builder.RunAsync();
关键原理说明
- 原代码中
StdSchedulerFactory.GetDefaultScheduler()创建的Scheduler使用Quartz默认作业工厂,仅支持无参构造函数的作业,无法识别.NET DI容器中的服务。 - 通过
UseMicrosoftDependencyInjectionJobFactory()或手动设置MicrosoftDependencyInjectionJobFactory,让Quartz使用.NET DI容器创建作业实例,从而自动注入IRepository等依赖服务。
内容的提问来源于stack exchange,提问作者Another Weeb
相关产品推荐
相关产品推荐

