使用Quartz.NET和Simple Injector进行构造函数注入

The*_*ads 36 .net c# dependency-injection quartz.net simple-injector

目前我正在使用Quartz.NET编写一个服务来安排它的运行.

我想知道是否有人有任何使用Quartz.NET和Simple Injector构造函数注入的经验.

以下基本上是我希望实现的目标

public class JobImplementation: IJob
{
    private readonly IInjectedClass injectedClass;

    public JobImplementation(IInjectedClass _injectedClass)
    {
         injectedClass = _injectedClass
    }

    public void Execute(IJobExecutionContext _context)
    {
        //Job code
    }
Run Code Online (Sandbox Code Playgroud)

Ste*_*ven 42

根据这篇博客文章,你需要实现一个自定义IJobFactory,如下所示:

public class SimpleInjectorJobFactory : IJobFactory
{
    private readonly Container container;
    private readonly Dictionary<Type, InstanceProducer> jobProducers;

    public SimpleInjectorJobFactory(
        Container container, params Assembly[] assemblies)
    {
        this.container = container;

        // By creating producers, jobs can be decorated.
        var transient = Lifestyle.Transient;
        this.jobProducers =
            container.GetTypesToRegister(typeof(IJob), assemblies).ToDictionary(
                type => type,
                type => transient.CreateProducer(typeof(IJob), type, container));
    }

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler _)
    {
        var jobProducer = this.jobProducers[bundle.JobDetail.JobType];
        return new AsyncScopedJobDecorator(
            this.container, () => (IJob)jobProducer.GetInstance());
    }

    public void ReturnJob(IJob job)
    {
        // This will be handled automatically by Simple Injector
    }

    private sealed class AsyncScopedJobDecorator : IJob
    {
        private readonly Container container;
        private readonly Func<IJob> decorateeFactory;

        public AsyncScopedJobDecorator(
            Container container, Func<IJob> decorateeFactory)
        {
            this.container = container;
            this.decorateeFactory = decorateeFactory;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            using (AsyncScopedLifestyle.BeginScope(this.container))
            {
                var job = this.decorateeFactory();
                await job.Execute(context);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,您还需要以下注册:

var container = new Container();

container.Options.ScopedLifestyle = new AsyncScopedLifestyle();

var factory = new StdSchedulerFactory();

IScheduler scheduler = await factory.GetScheduler();

scheduler.JobFactory = new SimpleInjectorJobFactory(
    container, 
    Assembly.GetExecutingAssembly()); // assemblies that contain jobs

// Optional: register some decorators
container.RegisterDecorator(typeof(IJob), typeof(LoggingJobDecorator));

container.Verify();
Run Code Online (Sandbox Code Playgroud)

  • 我不得不搜索它,并认为注意以下石英配置是如何告诉它使用注入友好的作业工厂实现将是有帮助的:<add key ="quartz.scheduler.jobFactory.type"value ="YourNamespace .SimpleInjectorJobFactory,YourAssembly"/> (9认同)
  • 我必须以稍微不同的方式注册调度程序以将jobFactory放入其中.使用XML不起作用,因为它强制执行默认构造函数要求.所以除了Steven的帖子之外,我添加了container.RegisterSingle <IScheduler>(()=> {var scheduler = schedulerFactory.GetScheduler(); scheduler.JobFactory = container.GetInstance <IJobFactory>(); return scheduler;}); (8认同)
  • 大!另请注意,使用Quartz.Net 2.0,需要实现`public IJob NewJob(TriggerFiredBundle bundle,IScheduler scheduler){...}`.并且不确定是否应该在`public void ReturnJob(IJob job){...}`中实现任何清理调用. (2认同)