You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 15:20:23