Table of Contents

Class MicrosoftDependencyInjectionJobFactory

Namespace
Quartz.Impl
Assembly
Quartz.dll

Integrates job instantiation with Microsoft DI system.

public class MicrosoftDependencyInjectionJobFactory : PropertySettingJobFactory, IJobFactory
Inheritance
MicrosoftDependencyInjectionJobFactory
Implements
Inherited Members

Constructors

MicrosoftDependencyInjectionJobFactory(IServiceProvider, IOptions<JobFactoryOptions>?, ILoggerFactory?)

public MicrosoftDependencyInjectionJobFactory(IServiceProvider serviceProvider, IOptions<JobFactoryOptions>? options = null, ILoggerFactory? loggerFactory = null)

Parameters

serviceProvider IServiceProvider

The container jobs are built from.

options IOptions<JobFactoryOptions>

The factory's settings, which is where ConfigureScope arrives from. Optional so that a derived factory constructing this one by hand does not have to supply it; the container always does.

loggerFactory ILoggerFactory

Where the base factories create their loggers, so that "producing instance of job" and a property that did not match reach the application's logging. Optional for the same reason options is; the container always supplies it.

Methods

ConfigureScope(IServiceScope, TriggerFiredBundle, IScheduler)

Prepares the dependency injection scope a job is about to be built in.

protected virtual void ConfigureScope(IServiceScope scope, TriggerFiredBundle bundle, IScheduler scheduler)

Parameters

scope IServiceScope
bundle TriggerFiredBundle
scheduler IScheduler

Remarks

The configuration point for services that are scoped and need the ambient context of a job. It runs before the job is resolved, and is synchronous so that an AsyncLocal<T> set here survives into Execute.

Overriding this is no longer the only way to reach it: ConfigureScope is the same hook as a delegate, for an application that has no other reason to write a job factory. An override that does not call base takes the delegate's place.

CreateJobInstance(TriggerFiredBundle, IScheduler, CancellationToken)

protected override ValueTask<JobScope> CreateJobInstance(TriggerFiredBundle bundle, IScheduler scheduler, CancellationToken cancellationToken = default)

Parameters

bundle TriggerFiredBundle
scheduler IScheduler
cancellationToken CancellationToken

Returns

ValueTask<JobScope>

Remarks

Deliberately not an async method: an async state machine would restore the caller's ExecutionContext when its synchronous part returns, discarding any AsyncLocal<T> that ConfigureScope(IServiceScope, TriggerFiredBundle, IScheduler) set — which is most of the reason that hook exists (#1528).

ReturnJob(JobScope, CancellationToken)

Returns the job, closing the dependency injection scope it was built in.

public override ValueTask ReturnJob(JobScope scope, CancellationToken cancellationToken = default)

Parameters

scope JobScope
cancellationToken CancellationToken

Returns

ValueTask

Remarks

The scope is carried in State, and it knows whether the job is its to dispose: one the container resolved is registered with the scope and disposed by it, while one this factory activated itself is not, and is disposed here.

A derived factory that overrides CreateJobInstance(TriggerFiredBundle, IScheduler, CancellationToken) and returns state of its own takes over that decision completely: this method will not touch the job, and it disposes the replacement state only if that state is itself disposable. The replacement's disposal must therefore cascade to the state this factory produced — wrap it rather than discard it; it is IAsyncDisposable for exactly that reason. A derived factory whose replacement state is not disposable must override this method as well and do its own teardown.