Interface IQuartzBuilder
- Namespace
- Quartz
- Assembly
- Quartz.dll
Configures a scheduler and the services it is built from.
public interface IQuartzBuilder
- Extension Methods
Remarks
Every member configures typed options or registers a service — nothing writes configuration
strings. The option names are the same words as the configuration keys, so
Quartz:ThreadPool:MaxConcurrency and MaxConcurrency are the
same setting said two ways, and code-first and file-based configuration describe one vocabulary
rather than two.
Members return the builder so configuration can be chained.
Properties
SchedulerName
The name this scheduler was registered under, or an empty string for the default scheduler.
string SchedulerName { get; }
Property Value
Remarks
This is also the service key its components are registered under and the name of its options, so a named scheduler's registrations and configuration always agree.
Services
The services this scheduler is built from. Register your own implementations here to replace the defaults — anything registered wins over Quartz's own registration.
IServiceCollection Services { get; }
Property Value
Methods
AddJobListener<T>(params IReadOnlyCollection<IMatcher<JobKey>>)
IQuartzBuilder AddJobListener<T>(params IReadOnlyCollection<IMatcher<JobKey>> matchers) where T : class, IJobListener
Parameters
matchersIReadOnlyCollection<IMatcher<JobKey>>
Returns
Type Parameters
T
Remarks
The listener's shape is checked here, while the application is still writing its configuration. Every member of ISchedulerListener, IJobListener and ITriggerListener has a default implementation, so a public method that carries a notification's name but not its signature still compiles — it just stops implementing anything, and the default runs in its place with nothing to say the method is dead. Such a listener is refused with a SchedulerConfigException naming the member and the signature it should have.
What is examined is T: for an instance overload that is the type the call
was written with rather than the instance's own, so a listener handed over as its base type is
checked as that base, and a factory overload declared as the interface has nothing to examine at
all. Neither escapes — the listener's runtime type is checked again when it is attached to a
scheduler, which is only a later moment to hear about it.
AddJobListener<T>(Func<IServiceProvider, T>, params IReadOnlyCollection<IMatcher<JobKey>>)
IQuartzBuilder AddJobListener<T>(Func<IServiceProvider, T> factory, params IReadOnlyCollection<IMatcher<JobKey>> matchers) where T : class, IJobListener
Parameters
factoryFunc<IServiceProvider, T>matchersIReadOnlyCollection<IMatcher<JobKey>>
Returns
Type Parameters
T
Remarks
The listener's shape is checked here, while the application is still writing its configuration. Every member of ISchedulerListener, IJobListener and ITriggerListener has a default implementation, so a public method that carries a notification's name but not its signature still compiles — it just stops implementing anything, and the default runs in its place with nothing to say the method is dead. Such a listener is refused with a SchedulerConfigException naming the member and the signature it should have.
What is examined is T: for an instance overload that is the type the call
was written with rather than the instance's own, so a listener handed over as its base type is
checked as that base, and a factory overload declared as the interface has nothing to examine at
all. Neither escapes — the listener's runtime type is checked again when it is attached to a
scheduler, which is only a later moment to hear about it.
AddJobListener<T>(T, params IReadOnlyCollection<IMatcher<JobKey>>)
IQuartzBuilder AddJobListener<T>(T listener, params IReadOnlyCollection<IMatcher<JobKey>> matchers) where T : class, IJobListener
Parameters
listenerTmatchersIReadOnlyCollection<IMatcher<JobKey>>
Returns
Type Parameters
T
Remarks
The listener's shape is checked here, while the application is still writing its configuration. Every member of ISchedulerListener, IJobListener and ITriggerListener has a default implementation, so a public method that carries a notification's name but not its signature still compiles — it just stops implementing anything, and the default runs in its place with nothing to say the method is dead. Such a listener is refused with a SchedulerConfigException naming the member and the signature it should have.
What is examined is T: for an instance overload that is the type the call
was written with rather than the instance's own, so a listener handed over as its base type is
checked as that base, and a factory overload declared as the interface has nothing to examine at
all. Neither escapes — the listener's runtime type is checked again when it is attached to a
scheduler, which is only a later moment to hear about it.
AddJobMiddleware<T>()
Adds a middleware the container builds, which wraps every job this scheduler executes.
IQuartzBuilder AddJobMiddleware<T>() where T : class, IJobExecutionMiddleware
Returns
Type Parameters
TThe middleware's type.
Remarks
Middleware is where a cross-cutting concern lives — a log scope, a tenant context, a timeout, a translation of what a library throws. A listener cannot do any of those: it is notified before and after the job rather than around it, so it can neither wrap the call, decline to make it, nor see what it threw. See IJobExecutionMiddleware for what a middleware may and may not decide.
Middleware runs in registration order, outermost first, so the first registered is the first to see a firing and the last to see its result. Each call adds a stage: registering the same type twice puts it in the chain twice, the same way registering the same job twice schedules it twice.
One instance is built per scheduler and shared by every firing, so a middleware must keep no per-firing state in a field. It is registered for this scheduler alone, like its listeners and its job store, so a named scheduler's middleware wraps only its own executions.
That instance is built from the container's root, when the scheduler's resources are,
so its constructor dependencies must be singletons. A scoped one throws
Cannot resolve scoped service … from root provider where scope validation is on — the
Host's default in Development — and becomes a captive dependency living as long as the scheduler
where it is not. Take IServiceScopeFactory and open a scope inside Invoke instead,
or read the firing's own scope through IJobExecutionContextAccessor.
A middleware registered through ConfigureAllQuartzSchedulers always composes inside
one registered here, whichever call was written first: a scheduler's own callback runs before what
every scheduler was told, so a library's wrapper sits within the application's.
AddJobMiddleware<T>(Func<IServiceProvider, T>)
IQuartzBuilder AddJobMiddleware<T>(Func<IServiceProvider, T> factory) where T : class, IJobExecutionMiddleware
Parameters
factoryFunc<IServiceProvider, T>Builds the middleware from this scheduler's view of the container.
Returns
Type Parameters
TThe middleware's type.
Remarks
Middleware is where a cross-cutting concern lives — a log scope, a tenant context, a timeout, a translation of what a library throws. A listener cannot do any of those: it is notified before and after the job rather than around it, so it can neither wrap the call, decline to make it, nor see what it threw. See IJobExecutionMiddleware for what a middleware may and may not decide.
Middleware runs in registration order, outermost first, so the first registered is the first to see a firing and the last to see its result. Each call adds a stage: registering the same type twice puts it in the chain twice, the same way registering the same job twice schedules it twice.
One instance is built per scheduler and shared by every firing, so a middleware must keep no per-firing state in a field. It is registered for this scheduler alone, like its listeners and its job store, so a named scheduler's middleware wraps only its own executions.
That instance is built from the container's root, when the scheduler's resources are,
so its constructor dependencies must be singletons. A scoped one throws
Cannot resolve scoped service … from root provider where scope validation is on — the
Host's default in Development — and becomes a captive dependency living as long as the scheduler
where it is not. Take IServiceScopeFactory and open a scope inside Invoke instead,
or read the firing's own scope through IJobExecutionContextAccessor.
A middleware registered through ConfigureAllQuartzSchedulers always composes inside
one registered here, whichever call was written first: a scheduler's own callback runs before what
every scheduler was told, so a library's wrapper sits within the application's.
AddJobMiddleware<T>(T)
IQuartzBuilder AddJobMiddleware<T>(T middleware) where T : class, IJobExecutionMiddleware
Parameters
middlewareTThe middleware, already built.
Returns
Type Parameters
TThe middleware's type.
Remarks
Middleware is where a cross-cutting concern lives — a log scope, a tenant context, a timeout, a translation of what a library throws. A listener cannot do any of those: it is notified before and after the job rather than around it, so it can neither wrap the call, decline to make it, nor see what it threw. See IJobExecutionMiddleware for what a middleware may and may not decide.
Middleware runs in registration order, outermost first, so the first registered is the first to see a firing and the last to see its result. Each call adds a stage: registering the same type twice puts it in the chain twice, the same way registering the same job twice schedules it twice.
One instance is built per scheduler and shared by every firing, so a middleware must keep no per-firing state in a field. It is registered for this scheduler alone, like its listeners and its job store, so a named scheduler's middleware wraps only its own executions.
That instance is built from the container's root, when the scheduler's resources are,
so its constructor dependencies must be singletons. A scoped one throws
Cannot resolve scoped service … from root provider where scope validation is on — the
Host's default in Development — and becomes a captive dependency living as long as the scheduler
where it is not. Take IServiceScopeFactory and open a scope inside Invoke instead,
or read the firing's own scope through IJobExecutionContextAccessor.
A middleware registered through ConfigureAllQuartzSchedulers always composes inside
one registered here, whichever call was written first: a scheduler's own callback runs before what
every scheduler was told, so a library's wrapper sits within the application's.
AddPlugin<T>(Func<IServiceProvider, T>, string?)
Adds a plugin the caller builds and configures.
IQuartzBuilder AddPlugin<T>(Func<IServiceProvider, T> factory, string? name = null) where T : class, ISchedulerPlugin
Parameters
factoryFunc<IServiceProvider, T>Builds the plugin.
namestringThe name the scheduler knows the plugin by.
Returns
Type Parameters
TThe plugin's type.
Remarks
The three shapes match the listener trio: the container builds the plugin, the caller builds it,
or the caller configures options the plugin is given. name is how the
scheduler refers to the plugin, and some plugins derive persisted job and trigger keys from it —
so it is part of the deployment's identity rather than a label, and it is also the name a
quartz.plugin.<name>.* key configures the same plugin under. Left unset, the
plugin's type name is used. Plugins shipped with Quartz use their conventional short name
(xml, json) for that reason.
AddPlugin<T>(string?)
Adds a plugin, which extends the scheduler's behaviour for its whole lifetime.
IQuartzBuilder AddPlugin<T>(string? name = null) where T : class, ISchedulerPlugin
Parameters
namestringThe name the scheduler knows the plugin by.
Returns
Type Parameters
TThe plugin's type.
Remarks
The three shapes match the listener trio: the container builds the plugin, the caller builds it,
or the caller configures options the plugin is given. name is how the
scheduler refers to the plugin, and some plugins derive persisted job and trigger keys from it —
so it is part of the deployment's identity rather than a label, and it is also the name a
quartz.plugin.<name>.* key configures the same plugin under. Left unset, the
plugin's type name is used. Plugins shipped with Quartz use their conventional short name
(xml, json) for that reason.
AddPlugin<T, TOptions>(Action<TOptions>?, string?)
Adds a plugin with configuration of its own.
IQuartzBuilder AddPlugin<T, TOptions>(Action<TOptions>? configure = null, string? name = null) where T : class, ISchedulerPlugin where TOptions : class
Parameters
configureAction<TOptions>Configures the plugin's options.
namestringThe name the scheduler knows the plugin by.
Returns
Type Parameters
TThe plugin's type.
TOptionsThe plugin's options type, which it takes as a dependency. It is resolved through
IOptions<TOptions>, so it must keep its public parameterless constructor when the application is trimmed.
Remarks
The three shapes match the listener trio: the container builds the plugin, the caller builds it,
or the caller configures options the plugin is given. name is how the
scheduler refers to the plugin, and some plugins derive persisted job and trigger keys from it —
so it is part of the deployment's identity rather than a label, and it is also the name a
quartz.plugin.<name>.* key configures the same plugin under. Left unset, the
plugin's type name is used. Plugins shipped with Quartz use their conventional short name
(xml, json) for that reason.
AddSchedulerListener<T>()
Adds a scheduler listener the container builds.
IQuartzBuilder AddSchedulerListener<T>() where T : class, ISchedulerListener
Returns
Type Parameters
TThe listener's type.
Remarks
The listener's shape is checked here, while the application is still writing its configuration. Every member of ISchedulerListener, IJobListener and ITriggerListener has a default implementation, so a public method that carries a notification's name but not its signature still compiles — it just stops implementing anything, and the default runs in its place with nothing to say the method is dead. Such a listener is refused with a SchedulerConfigException naming the member and the signature it should have.
What is examined is T: for an instance overload that is the type the call
was written with rather than the instance's own, so a listener handed over as its base type is
checked as that base, and a factory overload declared as the interface has nothing to examine at
all. Neither escapes — the listener's runtime type is checked again when it is attached to a
scheduler, which is only a later moment to hear about it.
AddSchedulerListener<T>(Func<IServiceProvider, T>)
IQuartzBuilder AddSchedulerListener<T>(Func<IServiceProvider, T> factory) where T : class, ISchedulerListener
Parameters
factoryFunc<IServiceProvider, T>
Returns
Type Parameters
T
Remarks
The listener's shape is checked here, while the application is still writing its configuration. Every member of ISchedulerListener, IJobListener and ITriggerListener has a default implementation, so a public method that carries a notification's name but not its signature still compiles — it just stops implementing anything, and the default runs in its place with nothing to say the method is dead. Such a listener is refused with a SchedulerConfigException naming the member and the signature it should have.
What is examined is T: for an instance overload that is the type the call
was written with rather than the instance's own, so a listener handed over as its base type is
checked as that base, and a factory overload declared as the interface has nothing to examine at
all. Neither escapes — the listener's runtime type is checked again when it is attached to a
scheduler, which is only a later moment to hear about it.
AddSchedulerListener<T>(T)
IQuartzBuilder AddSchedulerListener<T>(T listener) where T : class, ISchedulerListener
Parameters
listenerT
Returns
Type Parameters
T
Remarks
The listener's shape is checked here, while the application is still writing its configuration. Every member of ISchedulerListener, IJobListener and ITriggerListener has a default implementation, so a public method that carries a notification's name but not its signature still compiles — it just stops implementing anything, and the default runs in its place with nothing to say the method is dead. Such a listener is refused with a SchedulerConfigException naming the member and the signature it should have.
What is examined is T: for an instance overload that is the type the call
was written with rather than the instance's own, so a listener handed over as its base type is
checked as that base, and a factory overload declared as the interface has nothing to examine at
all. Neither escapes — the listener's runtime type is checked again when it is attached to a
scheduler, which is only a later moment to hear about it.
AddTriggerListener<T>(params IReadOnlyCollection<IMatcher<TriggerKey>>)
IQuartzBuilder AddTriggerListener<T>(params IReadOnlyCollection<IMatcher<TriggerKey>> matchers) where T : class, ITriggerListener
Parameters
matchersIReadOnlyCollection<IMatcher<TriggerKey>>
Returns
Type Parameters
T
Remarks
The listener's shape is checked here, while the application is still writing its configuration. Every member of ISchedulerListener, IJobListener and ITriggerListener has a default implementation, so a public method that carries a notification's name but not its signature still compiles — it just stops implementing anything, and the default runs in its place with nothing to say the method is dead. Such a listener is refused with a SchedulerConfigException naming the member and the signature it should have.
What is examined is T: for an instance overload that is the type the call
was written with rather than the instance's own, so a listener handed over as its base type is
checked as that base, and a factory overload declared as the interface has nothing to examine at
all. Neither escapes — the listener's runtime type is checked again when it is attached to a
scheduler, which is only a later moment to hear about it.
AddTriggerListener<T>(Func<IServiceProvider, T>, params IReadOnlyCollection<IMatcher<TriggerKey>>)
IQuartzBuilder AddTriggerListener<T>(Func<IServiceProvider, T> factory, params IReadOnlyCollection<IMatcher<TriggerKey>> matchers) where T : class, ITriggerListener
Parameters
factoryFunc<IServiceProvider, T>matchersIReadOnlyCollection<IMatcher<TriggerKey>>
Returns
Type Parameters
T
Remarks
The listener's shape is checked here, while the application is still writing its configuration. Every member of ISchedulerListener, IJobListener and ITriggerListener has a default implementation, so a public method that carries a notification's name but not its signature still compiles — it just stops implementing anything, and the default runs in its place with nothing to say the method is dead. Such a listener is refused with a SchedulerConfigException naming the member and the signature it should have.
What is examined is T: for an instance overload that is the type the call
was written with rather than the instance's own, so a listener handed over as its base type is
checked as that base, and a factory overload declared as the interface has nothing to examine at
all. Neither escapes — the listener's runtime type is checked again when it is attached to a
scheduler, which is only a later moment to hear about it.
AddTriggerListener<T>(T, params IReadOnlyCollection<IMatcher<TriggerKey>>)
IQuartzBuilder AddTriggerListener<T>(T listener, params IReadOnlyCollection<IMatcher<TriggerKey>> matchers) where T : class, ITriggerListener
Parameters
listenerTmatchersIReadOnlyCollection<IMatcher<TriggerKey>>
Returns
Type Parameters
T
Remarks
The listener's shape is checked here, while the application is still writing its configuration. Every member of ISchedulerListener, IJobListener and ITriggerListener has a default implementation, so a public method that carries a notification's name but not its signature still compiles — it just stops implementing anything, and the default runs in its place with nothing to say the method is dead. Such a listener is refused with a SchedulerConfigException naming the member and the signature it should have.
What is examined is T: for an instance overload that is the type the call
was written with rather than the instance's own, so a listener handed over as its base type is
checked as that base, and a factory overload declared as the interface has nothing to examine at
all. Neither escapes — the listener's runtime type is checked again when it is attached to a
scheduler, which is only a later moment to hear about it.
ConfigureOptions<TOptions>(Action<TOptions>?)
Configures an options type belonging to this scheduler, so a component of your own can have settings that follow the scheduler it was registered for.
IQuartzBuilder ConfigureOptions<TOptions>(Action<TOptions>? configure = null) where TOptions : class
Parameters
configureAction<TOptions>Configures the options.
Returns
Type Parameters
TOptionsThe options type. It is resolved through
IOptions<TOptions>, so it must keep its public parameterless constructor when the application is trimmed.
Remarks
A component the container builds asks for IOptions<TOptions>, which by itself
resolves the unnamed instance — so under AddQuartz("reporting", …) it would be
handed the default scheduler's settings, or defaults. This says the type is a scheduler's own:
the callback is registered under this scheduler's options name, and the type is declared so that
resolving it through the scheduler hands back the named instance.
Registered whether or not a callback is given: where the options come from is not something adding one should change. Calling it repeatedly is harmless — each callback is applied in turn, and the declaration is deduplicated.
This is the mechanism AddPlugin<T, TOptions>(Action<TOptions>?, string?) is built from, available to every component: a thread pool, a job store, a lock handler, a listener, a job factory.
ConfigureScheduler(Action<QuartzSchedulerOptions>)
Configures the scheduler itself.
IQuartzBuilder ConfigureScheduler(Action<QuartzSchedulerOptions> configure)
Parameters
configureAction<QuartzSchedulerOptions>
Returns
UseDefaultThreadPool(Action<ThreadPoolOptions>?)
Uses the default thread pool.
IQuartzBuilder UseDefaultThreadPool(Action<ThreadPoolOptions>? configure = null)
Parameters
configureAction<ThreadPoolOptions>
Returns
UseDefaultThreadPool(int)
Uses the default thread pool, limited to the given number of concurrently executing jobs.
IQuartzBuilder UseDefaultThreadPool(int maxConcurrency)
Parameters
maxConcurrencyint
Returns
UseExecutionLimits(Action<ExecutionLimitsBuilder>)
Configures execution group limits, so resource-hungry jobs cannot saturate every thread. Each limit is counted on this node or across the cluster, as its ExecutionLimitScope says.
IQuartzBuilder UseExecutionLimits(Action<ExecutionLimitsBuilder> configure)
Parameters
configureAction<ExecutionLimitsBuilder>
Returns
UseInMemoryStore(Action<InMemoryJobStoreOptions>?)
Uses the in-memory job store, which does not survive process restarts.
IQuartzBuilder UseInMemoryStore(Action<InMemoryJobStoreOptions>? configure = null)
Parameters
configureAction<InMemoryJobStoreOptions>
Returns
Remarks
Takes an options object rather than a sub-builder, unlike UsePersistentStore(Action<IPersistentStoreBuilder>): an in-memory store is one component with a couple of settings, whereas a database-backed store is a composite that also has a data source, a driver delegate, a serializer and a lock handler to choose. The shape says which kind of thing is being configured.
UseInstanceIdGenerator(IInstanceIdGenerator)
Uses an instance id generator the caller has already built.
IQuartzBuilder UseInstanceIdGenerator(IInstanceIdGenerator generator)
Parameters
generatorIInstanceIdGeneratorThe generator.
Returns
Remarks
Choosing a generator says the id is to be generated, so
GenerateInstanceId is set — the counterpart of writing
quartz.scheduler.instanceId = AUTO beside the generator's type name. A generator that was
chosen and then never called would be the configuration equivalent of silence.
Only a clustered scheduler generates one: a scheduler that shares its database with nobody has
nothing to tell itself apart from, so the generator is not called and the id stays
NON_CLUSTERED.
UseInstanceIdGenerator<T>()
Uses a specific instance id generator, which names this node within a cluster.
IQuartzBuilder UseInstanceIdGenerator<T>() where T : class, IInstanceIdGenerator
Returns
Type Parameters
TThe generator's type.
Remarks
Choosing a generator says the id is to be generated, so
GenerateInstanceId is set — the counterpart of writing
quartz.scheduler.instanceId = AUTO beside the generator's type name. A generator that was
chosen and then never called would be the configuration equivalent of silence.
Only a clustered scheduler generates one: a scheduler that shares its database with nobody has
nothing to tell itself apart from, so the generator is not called and the id stays
NON_CLUSTERED.
UseInstanceIdGenerator<T, TOptions>(Action<TOptions>?)
Uses an instance id generator with options of its own.
IQuartzBuilder UseInstanceIdGenerator<T, TOptions>(Action<TOptions>? configure = null) where T : class, IInstanceIdGenerator where TOptions : class
Parameters
configureAction<TOptions>Configures the generator's options.
Returns
Type Parameters
TThe generator's type.
TOptionsThe generator's options type. It is resolved through
IOptions<TOptions>, so it must keep its public parameterless constructor when the application is trimmed.
Remarks
Choosing a generator says the id is to be generated, so
GenerateInstanceId is set — the counterpart of writing
quartz.scheduler.instanceId = AUTO beside the generator's type name. A generator that was
chosen and then never called would be the configuration equivalent of silence.
Only a clustered scheduler generates one: a scheduler that shares its database with nobody has
nothing to tell itself apart from, so the generator is not called and the id stays
NON_CLUSTERED.
UseJobFactory(IJobFactory)
Uses a job factory the caller has already built.
IQuartzBuilder UseJobFactory(IJobFactory jobFactory)
Parameters
jobFactoryIJobFactory
Returns
UseJobFactory<T>()
Uses a specific job factory, which decides how job instances are produced.
IQuartzBuilder UseJobFactory<T>() where T : class, IJobFactory
Returns
Type Parameters
T
UseJobStore(IJobStore)
Uses a job store the caller has already built.
IQuartzBuilder UseJobStore(IJobStore jobStore)
Parameters
jobStoreIJobStore
Returns
Remarks
For a store that needs constructing with something the container cannot supply. A store the container can build is better selected with UseJobStore<T>(), UsePersistentStore<T>(Action<IPersistentStoreBuilder>) or UseInMemoryStore(Action<InMemoryJobStoreOptions>?), which let it have dependencies of its own.
UseJobStore(Func<IServiceProvider, IJobStore>)
Uses a job store built by a factory of your own.
IQuartzBuilder UseJobStore(Func<IServiceProvider, IJobStore> factory)
Parameters
factoryFunc<IServiceProvider, IJobStore>Builds the job store.
Returns
Remarks
For a store that needs something the container cannot construct on its own — a decorator around another store, or one whose constructor takes values rather than services. The factory is given this scheduler's view of the container and runs once, when the scheduler is built.
UseJobStore<T>()
Uses a job store of your own, built by the container.
IQuartzBuilder UseJobStore<T>() where T : class, IJobStore
Returns
Type Parameters
TThe job store's type.
Remarks
The seam for a store that keeps scheduling data somewhere Quartz has never heard of. It is constructed with this scheduler's own collaborators — its signaler, its serializer, its type loader — so a store written against them behaves the same under a named scheduler as under the default one. UseInMemoryStore(Action<InMemoryJobStoreOptions>?) and UsePersistentStore<T>(Action<IPersistentStoreBuilder>) remain the way to select the stores Quartz ships, since they configure them as well as choose them.
UseJobStore<T, TOptions>(Action<TOptions>?)
Uses a job store of your own, with options of its own.
IQuartzBuilder UseJobStore<T, TOptions>(Action<TOptions>? configure = null) where T : class, IJobStore where TOptions : class
Parameters
configureAction<TOptions>Configures the store's options.
Returns
Type Parameters
TThe job store's type.
TOptionsThe store's options type. It is resolved through
IOptions<TOptions>, so it must keep its public parameterless constructor when the application is trimmed.
Remarks
Sugar over UseJobStore<T>() and ConfigureOptions<TOptions>(Action<TOptions>?): the options
are declared as this scheduler's, so a store that takes IOptions<TOptions> is handed
what was configured for the scheduler it belongs to rather than the unnamed instance.
UsePersistentStore(Action<IPersistentStoreBuilder>)
Uses a database-backed job store, so jobs and triggers survive restarts and can be clustered.
IQuartzBuilder UsePersistentStore(Action<IPersistentStoreBuilder> configure)
Parameters
configureAction<IPersistentStoreBuilder>
Returns
Remarks
Takes a sub-builder rather than an options object, unlike UseInMemoryStore(Action<InMemoryJobStoreOptions>?): a database-backed store is a composite that also has a data source, a driver delegate, a serializer and a lock handler to choose.
Both stores Quartz ships are reached from here. The default begins the transaction each operation runs in and commits or rolls it back; UseAmbientTransactions() inside the callback selects the one that runs inside a transaction somebody else owns. UsePersistentStore<T>(Action<IPersistentStoreBuilder>) is for a store neither of those describes.
UsePersistentStore<T>(Action<IPersistentStoreBuilder>)
Uses a specific database-backed job store implementation.
IQuartzBuilder UsePersistentStore<T>(Action<IPersistentStoreBuilder> configure) where T : class, IJobStore
Parameters
configureAction<IPersistentStoreBuilder>
Returns
Type Parameters
T
Remarks
For a persistent store of your own. The two Quartz ships are both selected by UsePersistentStore(Action<IPersistentStoreBuilder>), which is why naming one of them here and also calling UseAmbientTransactions() is reported as the contradiction it is rather than silently resolved.
UseThreadPool(IThreadPool)
Uses a thread pool the caller has already built.
IQuartzBuilder UseThreadPool(IThreadPool threadPool)
Parameters
threadPoolIThreadPool
Returns
Remarks
For a pool that needs constructing with something the container cannot supply. A pool the container can build is better selected with UseThreadPool<T>(), which lets it have dependencies of its own.
UseThreadPool<T>()
Uses a specific thread pool implementation.
IQuartzBuilder UseThreadPool<T>() where T : class, IThreadPool
Returns
Type Parameters
T
Remarks
A pool of your own has options of its own: declare them with
ConfigureOptions<TOptions>(Action<TOptions>?) and take IOptions<TOptions> through its
constructor. ThreadPoolOptions belongs to the built-in pools, so it is configured
on UseDefaultThreadPool(Action<ThreadPoolOptions>?) where it is read.
UseTimeProvider(TimeProvider)
Uses a specific time provider. Useful for testing time-dependent scheduling.
IQuartzBuilder UseTimeProvider(TimeProvider timeProvider)
Parameters
timeProviderTimeProvider
Returns
Remarks
The clock belongs to this scheduler. Handing one to a named scheduler leaves the others on whatever they were using, which is what lets one scheduler in a container be driven by a fake clock while the rest keep real time.
A scheduler that was not given one asks the container, and falls back to System. In full, most specific first:
- the provider this scheduler was given here;
- a TimeProvider registered in the container;
- a
quartz.timeProvider.typekey, which loses to both — code beats strings here as it does everywhere else; - System.
UseTypeLoader<T>()
Uses a specific type loader, which decides how type names are resolved.
IQuartzBuilder UseTypeLoader<T>() where T : class, ITypeLoader
Returns
Type Parameters
T