Quartz,Unity和.NET

j04*_*d20 6 .net c# unity-container quartz.net

是否可以注册石英作业以始终使用IJob由DI容器Unity注入的相同实例?我有一个Monitor来自Unity DI 的类的"监视器" ,我注册为:

container.RegisterType<IMonitor, Monitor>(new ContainerControlledLifetimeManager())
Run Code Online (Sandbox Code Playgroud)

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

class MyJob : IJob {
...
[Dependency] IMonitor monitor {get; set;}
...
void Execute()
...
}
Run Code Online (Sandbox Code Playgroud)

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

谢谢

Dmi*_*try 5

Quartz将在每个fire事件上重新实现作业接口实现.这是推荐使用IStatefulJob,如果你想工作执行之间保持状态:

IStatefulJob实例遵循与常规IJob实例略有不同的规则.关键的区别在于,每次执行作业后都会重新保存关联的JobDataMap,从而保留下次执行的状态.另一个区别是有状态作业不允许同时执行,这意味着在IJob.Execute方法完成之前发生的新触发器将被延迟.

来自Quartz 教程:

StatefulJob

现在,关于作业状态数据(也称为JobDataMap)的一些附加说明:作业实例可以定义为"有状态"或"无状态".非有状态作业仅在将JobDataMap添加到调度程序时存储它们.这意味着在执行作业期间对作业数据映射的内容所做的任何更改都将丢失,并且下次执行时作业将不会看到这些更改.您可能已经猜到,有状态的工作正好相反 - 每次执行作业后都会重新存储JobDataMap.使工作成为有状态的一个副作用是它不能同时执行.或者换句话说:如果作业是有状态的,并且触发器在其已经执行时尝试"触发"该作业,则触发器将阻塞(等待)直到上一次执行完成.

通过让Job实现StatefulJob接口而不是Job接口,您可以将Job标记为有状态.

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

工作'实例'

关于这个主题的最后一点,现在可能或者可能不是很明显:您可以通过创建多个JobDetails实例来创建单个作业类,并在调度程序中存储它的许多"实例定义" - 每个实例都有自己的一组属性和JobDataMap - 并将它们全部添加到调度程序.

触发器触发时,与其关联的作业将通过Scheduler上配置的JobFactory实例化.默认的JobFactory只是在作业类上调用newInstance().您可能希望创建自己的JobFactory实现来完成诸如让应用程序的IoC或DI容器生成/初始化作业实例之类的事情.

  • 将引用存储在JobDataMap中的"监视器"或实现自己的JobFactory. (2认同)

Tim*_*ver 5

看看Quartz.Unity.

https://www.nuget.org/packages/Quartz.Unity/1.0.1

Doc非常稀疏,但似乎您需要做的就是将nuget包和以下行添加到容器配置中.

var container = new UnityContainer().AddNewExtension<Quartz.Unity.QuartzUnityExtension>();
Run Code Online (Sandbox Code Playgroud)