问题描述
目前,我正在使用Quartz.NET编写一个服务来安排运行它。
Currently I am writing a service using Quartz.NET to schedule the running of it.
我想知道有没有人有任何使用Quartz的构造器注入的经验。 NET和简单的注射器。
I was wondering if anyone has any experience of using constructor injection with Quartz.NET and Simple Injector.
下面基本上是我想要实现的。
Below is essentially what I wish to achieve
public class JobImplementation: IJob
{
private readonly IInjectedClass injectedClass;
public JobImplementation(IInjectedClass _injectedClass)
{
injectedClass = _injectedClass
}
public void Execute(IJobExecutionContext _context)
{
//Job code
}
推荐答案
根据,您需要实现一个自定义的 IJobFactory
,如下所示:
According to this blog post, you would need to implement a custom IJobFactory
, like this:
public class SimpleInjectorJobFactory : IJobFactory
{
private readonly Dictionary<Type, InstanceProducer> jobProducers;
public SimpleInjectorJobFactory(Container container, Assembly[] assemblies)
{
var types = container.GetTypesToRegister(typeof(IJob), assemblies);
var lifestyle = Lifestyle.Transient;
// By creating producers here by the IJob service type, jobs can be decorated.
this.jobProducers = (
from type in types
let producer = lifestyle.CreateProducer(typeof(IJob), type, container)
select new { type, producer })
.ToDictionary(t => t.type, t => t.producer);
}
public IJob NewJob(TriggerFiredBundle bundle)
{
return (IJob)this.jobProducers[bundle.JobDetail.JobType].GetInstance();
}
}
此外,在博客文章之后,您将需要以下注册:
Furthermore, following the blog post, you'll need the following registrations:
var container = new Container();
var schedulerFactory = new StdSchedulerFactory();
container.RegisterSingle<IJobFactory>(
new SimpleInjectorJobFactory(container, applicationAssemblies));
container.RegisterSingle<ILoadServiceScheduler, TimerScheduler>();
container.RegisterSingle<ISchedulerFactory>(schedulerFactory);
container.Register<IScheduler>(() => schedulerFactory.GetScheduler());
// Optional: register some decorators
container.RegisterDecorator(typeof(IJob), typeof(LoggingJobDecorator));
container.Verify();
如果您具有范围生活方式的注册,则创建和执行工作应包含在一个范围。这可以通过使用装饰器来实现:
In case you have any registrations with the scoped lifestyle, the creation and execution of jobs should be wrapped with a scope. This can be done for instance by using a decorator:
public class LifestyleScopeJobDecorator: IJob
{
private readonly Container container;
private readonly Func<IJob> decorateeFactory;
public LifestyleScopeJobDecorator(Container container, Func<IJob> decorateeFactory) {
this.container = container;
this.decorateeFactory = decorateeFactory;
}
public void Execute(IJobExecutionContext context) {
using (this.container.BeginLifetimeScope()) {
var job = this.decorateeFactory();
job.Execute(context);
}
}
}
将装饰器注册为最后装饰器如下
And registering the decorator as last decorator as follows
container.RegisterDecorator<IJob, LifetimeScopeJobDecorator>(Lifestyle.Singleton);
这有效地延迟了真实作业的创建,直到装饰器被执行的时刻。这允许在整个对象图中注入范围限定的服务(在这种情况下为LifetimeScope)。
This effectively delays the creation of the real job till the moment that the decorator is executed. This allows scoped services (LifetimeScope in this case) to be injected throughout the object graph.
这篇关于Quartz.NET和简单注射器的构造器注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!