Table of Contents

Class PropertySettingJobFactory

Namespace
Quartz.Impl
Assembly
Quartz.dll

A JobFactory that instantiates the Job instance (using its public parameterless constructor), and then attempts to set all values from the IJobExecutionContext's merged JobDataMap onto properties of the job.

public class PropertySettingJobFactory : SimpleJobFactory, IJobFactory
Inheritance
PropertySettingJobFactory
Implements
Derived
Inherited Members

Remarks

By default an entry in the JobDataMap that does not map to a property on your job class is ignored, because a map is allowed to carry values the job reads for itself. Set PropertyMismatchBehavior to Warn to log those — useful for troubleshooting a misspelled property name, noisy if you regularly (and purposely) have extra things in your map — or to Throw to fail the instantiation outright.

Constructors

PropertySettingJobFactory(ILoggerFactory?)

public PropertySettingJobFactory(ILoggerFactory? loggerFactory = null)

Parameters

loggerFactory ILoggerFactory

Where this factory and its derived types create their loggers. A factory the container builds is handed the application's; one constructed by hand — UseJobFactory(instance) — is handed nothing and reads LogProvider, as before. A factory rather than a logger, because PropertySettingJobFactory logs under its own category and has to be able to pass the same source down.

Properties

PropertyMismatchBehavior

What happens when a key (name) and value (type) found in the JobDataMap does not correspond to a property setter on the job class. Defaults to Ignore.

public virtual PropertyMismatchBehavior PropertyMismatchBehavior { get; set; }

Property Value

PropertyMismatchBehavior

Methods

BuildJobDataMap(TriggerFiredBundle, IScheduler)

Builds the map whose entries are applied to the job's properties: the trigger's data merged over the job's.

protected virtual JobDataMap BuildJobDataMap(TriggerFiredBundle bundle, IScheduler scheduler)

Parameters

bundle TriggerFiredBundle
scheduler IScheduler

Returns

JobDataMap

Remarks

Until 4.0 the scheduler context was merged in as well, underneath both. That injected every context entry into every fire — including the service-provider entry the DI integration seeds, which no job has a property for, so with Throw every container-hosted fire failed. A job that wants a context value reads context.Scheduler.Context in Execute(IJobExecutionContext, CancellationToken); a factory that wants the old behavior overrides this method, which is handed the scheduler for exactly that reason.

ConvertValueIfNecessary(Type, object?)

Coerces a JobDataMap value into the type the job's property takes.

protected virtual object? ConvertValueIfNecessary(Type requiredType, object? newValue)

Parameters

requiredType Type
newValue object

Returns

object

Remarks

The seam a derived factory overrides to convert a value some other way. It is deliberately the only thing between the map and the property, so an override sees every value the factory binds.

CreateJob(TriggerFiredBundle, IScheduler, CancellationToken)

Called by the scheduler at the time of the trigger firing, in order to produce a IJob instance on which to call Execute.

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

Parameters

bundle TriggerFiredBundle

The TriggerFiredBundle from which the IJobDetail and other info relating to the trigger firing can be obtained.

scheduler IScheduler

The scheduler the job will run under, made available to the job through its execution context.

cancellationToken CancellationToken

The cancellation instruction.

Returns

ValueTask<JobScope>

the newly instantiated Job

Remarks

It should be extremely rare for this method to throw an exception - basically only the case where there is no way at all to instantiate and prepare the Job for execution. When the exception is thrown, the Scheduler will move all triggers associated with the Job into the Error state, which will require human intervention (e.g. an application restart after fixing whatever configuration problem led to the issue with instantiating the Job).

Exceptions

SchedulerException

The job could not be instantiated, or a value in the merged job data map does not match a settable property of the job and PropertyMismatchBehavior says to throw.

CreateJobInstance(TriggerFiredBundle, IScheduler, CancellationToken)

Produces the job instance, before any JobDataMap properties are applied to it.

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

Parameters

bundle TriggerFiredBundle

The TriggerFiredBundle from which the IJobDetail and other info relating to the trigger firing can be obtained.

scheduler IScheduler

a handle to the scheduler that is about to execute the job

cancellationToken CancellationToken

The cancellation instruction.

Returns

ValueTask<JobScope>

Remarks

This is the extension point for derived factories that need to change how the job is built — resolving it from a container, for example — without overriding CreateJob(TriggerFiredBundle, IScheduler, CancellationToken) and reimplementing the property setting this class exists to provide.

It returns a ValueTask<TResult> so an override can await, but prefer to keep the synchronous path synchronous: an async override puts the work inside a state machine, which restores the caller's ExecutionContext when its synchronous part returns and so discards any AsyncLocal<T> the override set. Ambient context established here has to survive into Execute(IJobExecutionContext, CancellationToken) (#1528). Return a completed ValueTask<TResult> when nothing needs awaiting.

SetObjectProperties(object, JobDataMap)

Sets the object properties.

public virtual void SetObjectProperties(object obj, JobDataMap data)

Parameters

obj object

The object to set properties to.

data JobDataMap

The data to set.

SetObjectProperty(object, string, object?)

Sets specific property to object, handles conversion and error conditions.

[UnconditionalSuppressMessage("Trimming", "IL2075", Justification = "The job instance is of the job detail's declared type or of a registered implementation of it, and both are annotated where they enter Quartz. See the remarks.")]
protected virtual void SetObjectProperty(object job, string name, object? value)

Parameters

job object

Job instance to set property value to.

name string

Property name to set.

value object

Value to set.

Remarks

The property is found on the instance's own type rather than on the job detail's declared one, because a factory is allowed to hand back something else — AddJobType<TJob, TImpl> registers exactly that — and the data belongs to whatever was built. Both of those types are annotated where they enter Quartz, so their public properties survive trimming; the analyzer cannot see the link because the instance arrives here as an object. A job factory written from scratch that returns a type nothing else references is the one case this does not cover, and such a factory has to root its own jobs.

See Also