简体   繁体   English

使用依赖注入调度 Quartz.net 作业

[英]Scheduling a Quartz.net Job with dependency-injection

I'm working on my first project with EF Core, and Dependency Injecion for the DB Context.我正在使用 EF Core 和 DB Context 的依赖注入开发我的第一个项目。 However I'm running into an issue because Quartz.net 3 seems to not allow any parameters on the ImportJob Class.但是我遇到了一个问题,因为 Quartz.net 3 似乎不允许 ImportJob 类上的任何参数。 So my method of DI, doesn't work in this instance.所以我的 DI 方法在这种情况下不起作用。 I know I want a new context, because this is going to run in the background, is there a different way to create a DB Context so that I can Execute this task?我知道我想要一个新的上下文,因为这将在后台运行,是否有不同的方法来创建数据库上下文以便我可以执行此任务?

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

One way is to use the StdSchedulerFactory , a Job Factory that implements IJobFactory and takes a IServiceProvider一种方法是使用StdSchedulerFactory ,这是一个实现IJobFactory并采用IServiceProvider的作业工厂

Example例子

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

Depending on your DI framework the registrations would look a little like this根据您的 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);

Then you jobs can look like this然后你的工作可以看起来像这样

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

Note : This is the basic idea not a complete example, and it will depend a lot on your own setup and framework注意:这是一个基本的想法,不是一个完整的例子,它很大程度上取决于你自己的设置和框架

In short, what the above does is when Quartz creates a job it uses your Factory and container to spin up the job allowing for injection.简而言之,当 Quartz 创建一个作业时,它会使用您的工厂和容器来启动该作业以进行注入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM