提问者:小点点

。净岩心石英依赖注入


如何在 .net 核心中配置 Quartz 以使用依赖注入?我使用标准的.net核心依赖机制。在实现 IJob 的类的构造函数中,我需要注入一些依赖项。


共3个答案

匿名用户

您可以使用Quartz.Spi.IJobFactory接口并实现它。Quartz文档指出:

触发触发器时,将通过调度程序上配置的JobFactory实例化与其关联的作业。默认的JobFactory只是激活job类的一个新实例。您可能希望创建自己的JobFactory实现来完成一些事情,例如让应用程序的IoC或DI容器生成/初始化作业实例。请参阅IJobFactory接口和相关的调度程序。SetJobFactory(事实)方法。

ISchedulerFactory schedulerFactory = new StdSchedulerFactory(properties);
var scheduler = schedulerFactory.GetScheduler();

scheduler.JobFactory = jobFactory;

编辑

实现可以如下所示:

public class JobFactory : IJobFactory
{
    protected readonly IServiceProvider Container;

    public JobFactory(IServiceProvider container)
    {
        Container = container;
    }

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        return Container.GetService(bundle.JobDetail.JobType) as IJob;
    }

    public void ReturnJob(IJob job)
    {
        // i couldn't find a way to release services with your preferred DI, 
        // its up to you to google such things
    }
}

要将其与 Microsoft.Extensions.DependencyInjection 一起使用,请按如下方式创建容器:

var services = new ServiceCollection();
services.AddTransient<IAuthorizable, AuthorizeService>();
var container = services.BuildServiceProvider();
var jobFactory = new JobFactory(container);

参考

>

  • 石英文档

    应用程序接口

  • 匿名用户

    受到Rabbans伟大答案的启发,我为Microsoft.Extensions.DependencyInjection创建了一个完整的JobFactory实现:

    using Microsoft.Extensions.DependencyInjection;
    using Quartz;
    using Quartz.Spi;
    using System;
    using System.Collections.Concurrent;
    
    class JobFactory : IJobFactory
    {
        protected readonly IServiceProvider _serviceProvider;
    
        protected readonly ConcurrentDictionary<IJob, IServiceScope> _scopes = new ConcurrentDictionary<IJob, IServiceScope>();
    
        public JobFactory(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }
    
        public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
        {
            var scope = _serviceProvider.CreateScope();
            IJob job;
    
            try
            {
                job = scope.ServiceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;
            }
            catch
            {
                // Failed to create the job -> ensure scope gets disposed
                scope.Dispose();
                throw;
            }
    
            // Add scope to dictionary so we can dispose it once the job finishes
            if (!_scopes.TryAdd(job, scope))
            {
                // Failed to track DI scope -> ensure scope gets disposed
                scope.Dispose();
                throw new Exception("Failed to track DI scope");
            }
    
            return job;
        }
    
        public void ReturnJob(IJob job)
        {
            if (_scopes.TryRemove(job, out var scope))
            {
                // The Dispose() method ends the scope lifetime.
                // Once Dispose is called, any scoped services that have been resolved from ServiceProvider will be disposed.
                scope.Dispose();
            }
        }
    }
    
    // Prepare the DI container
    var services = new ServiceCollection();
    // Register job
    services.AddTransient<MyJob>();
    // Register job dependencies
    services.AddTransient<IFoo, Foo>();
    var container = services.BuildServiceProvider();
    
    // Create an instance of the job factory
    var jobFactory = new JobFactory(container);
    
    // Create a Quartz.NET scheduler
    var schedulerFactory = new StdSchedulerFactory(properties);
    var scheduler = schedulerFactory.GetScheduler();
    
    // Tell the scheduler to use the custom job factory
    scheduler.JobFactory = jobFactory;
    

    该实现已经在一个.NETCore2.1控制台应用程序中通过一个作业进行了测试,效果良好。请随时留下您的反馈或改进建议。。。

    匿名用户

    我知道这是个老问题,但只想补充一个2020年的答案:

    https://www.quartz-scheduler.net/documentation/quartz-3.x/packages/microsoft-di-integration.html

    https://www.quartz-scheduler.net/documentation/quartz-3.x/packages/aspnet-core-integration.html

    我发现它甚至比不使用.NET Core DI的方法更容易。然而,在我必须集成它的项目中,Autofac与MS DI一起使用(不能告诉你为什么),并且它抱怨一些依赖关系,所以我也必须添加以下映射:

    services.AddSingleton<ITypeLoadHelper, SimpleTypeLoadHelper>();
    

    我的总体解决方案如下:

    services.AddTransient<UpcomingReleasesNotificationJob>();
    services.AddSingleton<ITypeLoadHelper, SimpleTypeLoadHelper>();
    
    var jobKey = new JobKey("notificationJob");
    services.AddQuartz(q =>
    {
       q.SchedulerId = "JobScheduler";
       q.SchedulerName = "Job Scheduler";
       q.UseMicrosoftDependencyInjectionScopedJobFactory();
       q.AddJob<UpcomingReleasesNotificationJob>(j => j.WithIdentity(jobKey));
       q.AddTrigger(t => t
          .WithIdentity("notificationJobTrigger")
          .ForJob(jobKey)
          .StartNow()
          .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(14, 00))
       );
    });
    
    services.AddQuartzServer(options =>
    {
       options.WaitForJobsToComplete = true;
    });