kudlatiger
kudlatiger

Reputation: 3278

Quartz.SchedulerException: Problem instantiating class - Quartz is not executing as expected

This is my Job which needs to be executed every one minute, this has the dependency on logger

public class RefreshJob :IJob
{
    public RefreshJob(IContainerFactory containerFactory)
    {
        _logger = containerFactory.GetInstance<ILogger>();          
    }

    public Task Execute(IJobExecutionContext context)
    {
         return Task.Run(() =>
            {
                _logger.Information("Executing sample job");
                _logger.Information($"Name: {context.JobDetail.Key.Name}");
                _logger.Information($"Description: '{context.JobDetail.Description}'");
                _logger.Information($"Fire time utc: {context.FireTimeUtc:yyyy-MM-dd HH:mm:ss zzz}");
            });
    }
}

Here is my dependency injection

   var containerFactory = new ContainerFactory();//class with GetInstance method.
  _builder.Register(c => new RefreshJob(containerFactory)).SingleInstance();

This is how I get the scheduler reference

static async Task<IScheduler> GetScheduler()
{
    var factory = new StdSchedulerFactory();
    return await factory.GetScheduler();
}

and I use it in start method of my windows service

public void Start()
{
    Task<IScheduler> scheduler = GetScheduler();
    scheduler.Wait();
    _jobScheduler = scheduler.Result;
    _jobScheduler.Start();

    //Trigger
    IJobDetail job = JobBuilder.Create<RefreshCacheJob>().Build();
    ITrigger trigger = TriggerBuilder.Create()
        .WithIdentity("RefreshJob", "GroupName")
        .StartAt(DateTime.Now)
        .WithPriority(1)
        .Build();
    _jobScheduler.ScheduleJob(job, trigger);
}

But nothing happens. By the way, I am using Quartz scheduler inside windows service

Updated the error

Quartz.SchedulerException: Problem instantiating class 'Scheduler.RefreshJob' ---> System.ArgumentException: Cannot instantiate type which has no empty constructor Parameter name: RefreshJob

Upvotes: 4

Views: 8014

Answers (4)

NT Low
NT Low

Reputation: 11

The problem is await factory.GetScheduler();

Change to (await factory.GetAllSchedulers()).First(); then it should work

Somehow Quartz created 2 scheduler instances, and q.UseMicrosoftDependencyInjectionJobFactory(); only enabled Dependency Injection on the 1st scheduler, not the 2nd scheduler

While you call factory.GetScheduler(), it actually will return the 2nd scheduler instance which does not support Dependency Injection.

Upvotes: 1

drowhunter
drowhunter

Reputation: 379

So Setting UseMicrosoftDependencyInjectionJobFactory works

but the logs still show that error despite clearly injecting the services into the job.

Upvotes: 1

Chris Claude
Chris Claude

Reputation: 1372

If there's a need to inject a service into the job, follow this guide as @foips commented. Basically you need the following line in your DI container:

services.AddQuartz(q =>
{
    ...
    q.UseMicrosoftDependencyInjectionJobFactory();
    ...
}

Upvotes: 5

Ch1nmayK
Ch1nmayK

Reputation: 7

Quartz need an object to call the executed function, please create an empty constructor to instantiate an object Quartz can use.

as stated in this documentation

One of the ramifications of this behavior is the fact that jobs must have a no-argument constructor (when using the default JobFactory implementation).

Upvotes: -1

Related Questions