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

使用Quartz.NET+DI的控制台应用无法创建无空构造函数的Job

问题:Quartz Job无法通过依赖注入获取依赖对象,报错无空构造函数

报错信息:

Problem instantiating class 'test.MyJob: Cannot instantiate type which has no empty constructor (Parameter 'MyJob')'

用户代码如下:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Quartz;
using System.Diagnostics;

namespace test
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            var host = Host.CreateDefaultBuilder()
                .ConfigureServices((_, services) =>
                {
                    services.AddTransient<MyJob>();
                    services.AddTransient<IDog, Dog>();
                    services.AddQuartz(q =>
                    {
                        q.ScheduleJob<MyJob>(trigger => trigger
                            .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
                            );
                    });
                    services.AddQuartzHostedService();
                })
                .Build();
            await host.RunAsync();
        }
    }

    public interface IDog
    {
        string Name { get; }
    }

    public class Dog : IDog
    {
        public string Name => "Doge";
    }

    class MyJob : IJob
    {
        IDog _dog;
        public MyJob(IDog dog)
        {
            _dog= dog;
        }
        public Task Execute(IJobExecutionContext context)
        {
            Debug.WriteLine($"{_dog.Name} says {DateTime.Now}");
            return Task.CompletedTask;
        }
    }
}

项目文件:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
        <PackageReference Include="Quartz" Version="3.5.0" />
        <PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.5.0" />
        <PackageReference Include="Quartz.Extensions.Hosting" Version="3.5.0" />
    </ItemGroup>

</Project>

原因与解决方法

原因

Quartz默认的作业实例化逻辑是直接调用Job类型的构造函数,不会从依赖注入容器中获取实例。即使你把MyJob注册到了DI容器,ScheduleJob<T>的默认用法并没有告诉Quartz要使用DI来解析Job对象,所以它找不到无参构造函数就会抛出这个错误。

解决方法

方法一:显式注册Job并关联触发器

通过AddJob方法注册Job,明确指定从DI容器解析实例,再创建触发器关联该Job:

services.AddQuartz(q =>
{
    var jobKey = new JobKey("MyJob");
    // 注册Job,指定使用DI解析
    q.AddJob<MyJob>(jobKey, j => j.WithIdentity(jobKey));
    
    // 创建触发器并绑定到Job
    q.AddTrigger(t => t
        .WithIdentity("MyJobTrigger")
        .ForJob(jobKey)
        .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
    );
});

方法二:全局配置DI作业工厂

配置Quartz使用Microsoft的DI作业工厂,这样所有Job都会自动从DI容器中获取实例,原有的ScheduleJob<T>代码可以保留:

services.AddQuartz(q =>
{
    // 启用DI作业工厂,全局生效
    q.UseMicrosoftDependencyInjectionJobFactory();
    
    q.ScheduleJob<MyJob>(trigger => trigger
        .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
    );
});

两种方法都能解决问题,方法一适合针对单个Job配置,方法二是全局生效的配置,根据实际需求选择即可。


内容的提问来源于stack exchange,提问作者Damn Vegetables

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:35:17