使用依赖注入计划Quartz.net作业

时间:2019-04-03 23:17:53

标签: c# dependency-injection quartz-scheduler

我正在使用EF Core和DB Context的Dependency Injecion进行第一个项目。但是我遇到了一个问题,因为Quartz.net 3似乎不允许ImportJob类上的任何参数。所以我的DI方法在这种情况下不起作用。我知道我想要一个新的上下文,因为它将在后台运行,是否有其他方法可以创建数据库上下文,以便我可以执行此任务?

public class ImportJob : IJob
{
    private readonly SContext _db;

    //Quartz.net doesn't appear to like that I'm injecting these, 
    //because if I remove this parameter, execute...executes.
    public ImportJob(SContext db)
    {
        _db = db;
    }

    public Task Execute(IJobExecutionContext context)
    {
        var cc = new CC(_db);
        return Task.CompletedTask;
    }
}

1 个答案:

答案 0 :(得分:0)

一种方法是使用StdSchedulerFactory,它是实现IJobFactory并采用IServiceProvider的Job Factory

示例

public class JobFactory : IJobFactory
{
   private readonly IServiceProvider _serviceProvider;

   public JobFactory(IServiceProvider serviceProvider)
      => _serviceProvider = serviceProvider;

   public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
   {
      try
      {
         var jobDetail = bundle.JobDetail;
         var jobType = jobDetail.JobType;
         return _serviceProvider.GetService(jobType) as IJob;
      }
      catch (Exception ex)
      {

         throw new SchedulerException($"Problem instantiating class '{bundle.JobDetail.JobType.FullName}'", ex);
      }
   }

   public void ReturnJob(IJob job)
      => (job as IDisposable)?.Dispose();
}

根据您的DI框架,注册看起来像这样

// register, your container as an IServiceProvider
container.RegisterInstance<IServiceProvider>(container);

// create the scheduler
var scheduler = await StdSchedulerFactory.GetDefaultScheduler(cancellationTokenSource.Token);

// add your factory to the scheduler
scheduler.JobFactory = new JobFactory(container);

// register the scheduler
container.RegisterInstance(scheduler);

// register your jobs

container.Collection.Register<IJob>(GetType().Assembly);

然后您的工作看起来像这样

public class ImportJob : IJob
{
    private readonly SContext _db;

    //Quartz.net doesn't appear to like that I'm injecting these, 
    //because if I remove this parameter, execute...executes.
    public ImportJob(SContext db)
    {
        _db = db;
    }

    public Task Execute(IJobExecutionContext context)
    {
        var cc = new CC(_db);
        return Task.CompletedTask;
    }
}

注意 :这是基本概念,而不是完整的示例,它在很大程度上取决于您自己的设置和框架

简而言之,上面的操作是当Quartz创建一个 job 时,它使用您的Factory和 container 来启动该工作以进行注入。