C# · 12月 23, 2021

c# – Quartz,Unity和.NET

是否可以注册石英作业以始终使用由DI容器Unity注入的相同IJob实例?我有一个来自Unity DI的类Monitor的“监视器”,我注册为: container.RegisterType<IMonitor,Monitor>(new ContainerControlledLifetimeManager())

我的IJob实现期望将注入的监视器实例注入其中:

class MyJob : IJob {…[Dependency] IMonitor monitor {get; set;}…void Execute()…}

但是当quartz事件触发时,在注入依赖项之前调用IJob.Execute()实现.我应该如何工作?我应该考虑其他DI容器或调度程序吗?

谢谢

解决方法 Quartz将在每个fire事件上重新实现作业接口实现.如果要在作业执行之间保留状态,则使用IStatefulJob是 recommended:

IStatefulJob instances follow slightly different rules from regular
IJob instances. The key difference is that their associated JobDataMap
is re-persisted after every execution of the job,thus preserving
state for the next execution. The other difference is that stateful
jobs are not allowed to Execute concurrently,which means new triggers
that occur before the completion of the IJob.Execute method will be
delayed.

来自Quartz tutorial:

StatefulJob

Now,some additional notes about a job’s state data (aka JobDataMap):
A Job instance can be defined as “stateful” or “non-stateful”.
Non-stateful jobs only have their JobDataMap stored at the time they
are added to the scheduler. This means that any changes made to the
contents of the job data map during execution of the job will be lost,
and will not seen by the job the next time it executes. You have
probably guessed,a stateful job is just the opposite – its JobDataMap
is re-stored after every execution of the job. One side-effect of
making a job stateful is that it cannot be executed concurrently. Or
in other words: if a job is stateful,and a trigger attempts to ‘fire’
the job while it is already executing,the trigger will block (wait)
until the prevIoUs execution completes.

You ‘mark’ a Job as stateful by having it implement the StatefulJob
interface,rather than the Job interface.

另一个选择是实现自己的JobFactory:

Job ‘Instances’

One final point on this topic that may or may not be obvIoUs by Now:
You can create a single job class,and store many ‘instance
deFinitions’ of it within the scheduler by creating multiple instances
of JobDetails – each with its own set of properties and JobDataMap –
and adding them all to the scheduler.

When a trigger fires,the Job it is associated to is instantiated via
the JobFactory configured on the Scheduler. The default JobFactory
simply calls newInstance() on the job class. You may want to create your own implementation of JobFactory to accomplish things such as having your application’s IoC or DI container produce/initialize the job instance.