构造函数注射Quartz.NET和简单注射器 [英] Constructor injection with Quartz.NET and Simple Injector

查看:389
本文介绍了构造函数注射Quartz.NET和简单注射器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在写使用Quartz.NET安排它的运行的服务。



我想知道如果任何人有使用构造函数注射石英任何经验。 NET和简单的注射器。



下面基本上是什么,我希望实现



<预类=郎-CS prettyprint-覆盖> 公共类JobImplementation:IJob
{
私人只读IInjectedClass injectedClass;

公共JobImplementation(IInjectedClass _injectedClass)
{
injectedClass = _injectedClass
}

公共无效执行(IJobExecutionContext _context)
{
//工作代码
}


解决方案

根据这博客文章,你将需要实现自定义的 IJobFactory ,就像这样:



<预类=郎-cs prettyprint-覆盖> 公共类SimpleInjectorJobFactory:IJobFactory
{
私人只读字典<类型,InstanceProducer> jobProducers;

公共SimpleInjectorJobFactory(集装箱货柜,大会[]组件)
{
变种类型= container.GetTypesToRegister(typeof运算(IJob),组件);

VAR生活方式= Lifestyle.Transient;

//由IJob服务类型在这里创造生产,作业可以装饰。
this.jobProducers =(从类型
类中的
让制片= lifestyle.CreateProducer(typeof运算(IJob),类型,容器)
选择新的{类型,出品})
.ToDictionary(T => t.type,T => t.producer);
}

公共IJob NewJob(TriggerFiredBundle束)
{
回报(IJob)this.jobProducers [bundle.JobDetail.JobType] .GetInstance();
}
}



此外,继博客文章,你需要下列注册:



<预类=郎-CS prettyprint-覆盖> VAR集装箱=​​新容器();

变种schedulerFactory =新StdSchedulerFactory();

container.RegisterSingle< IJobFactory>(
新SimpleInjectorJobFactory(集装箱,applicationAssemblies));
container.RegisterSingle< ILoadServiceScheduler,TimerScheduler>();
container.RegisterSingle< ISchedulerFactory>(schedulerFactory);
container.Register&所述; IScheduler>(()=> schedulerFactory.GetScheduler());

//可选:注册一些装饰
container.RegisterDecorator(typeof运算(IJob)的typeof(LoggingJobDecorator));

container.Verify();

如果您有与范围的生活方式,创造和执行工作的登记应与被包装一个范围。这可以例如通过使用装饰来完成:

 公共类LifestyleScopeJobDecorator:IJob 
{
私人只读集装箱货柜;
私人只读Func键< IJob> decorateeFactory;

公共LifestyleScopeJobDecorator(集装箱货柜,Func键< IJob> decorateeFactory){
this.container =容器;
this.decorateeFactory = decorateeFactory;
}

公共无效执行(IJobExecutionContext上下文){用(this.container.BeginLifetimeScope()){
变种作业
= this.decorateeFactory();
job.Execute(上下文);
}
}
}

和注册的装饰在去年装饰如下:

  container.RegisterDecorator< IJob,LifetimeScopeJobDecorator>(Lifestyle.Singleton); 

这有效地延迟了真正的工作到那装饰执行时刻的创建。这允许范围的服务(在本例LifetimeScope),以在整个对象图被注入


Currently I am writing a service using Quartz.NET to schedule the running of it.

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
    }

解决方案

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);

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和简单注射器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆