在Quartz .NET的工作类中使用依赖注入

Quartz .NET默认的Execute方法是不支持非空的构造函数的,所以.net core常用的构造函数依赖注入也搞不来,网上搜索一番搞定了这个问题。

解决方案简单来说就是自定义一个任务工厂,替换Quartz的默认工厂,下面是一个小例子。

新建一个控制台项目,创建一个接口,一个类继承这个接口,它们用于展示依赖注入。

IMySql接口

namespace IMySql
{
    public interface IMySqlInterface
    {
        void Query();
    }
}

SqlServerHelpr类继承IMySql接口

using System;
using IMySql;

namespace MySqlServerTest
{
    public class SqlServerHelpr : IMySqlInterface
    {
        public void Query()
        {
            Console.WriteLine("使用SqlServer查询");
        }
    }
}

新建一个MyJob方法,这个是定时任务执行的方法

using System;
using System.Threading.Tasks;
using Quartz;
using IMySql;

namespace MyQuartz
{
    public class MyJob : IJob
    {
        private readonly IMySqlInterface _mySql;

        public MyJob(IMySqlInterface mySql)
        {
            _mySql = mySql;
        }

        public Task Execute(IJobExecutionContext context)
        {
            _mySql.Query();
            Console.WriteLine(DateTime.Now.ToLongTimeString());
            return Task.CompletedTask;
        }
    }
}

 

新建一个继承IJobFactory接口的类,这个类用于提供默认的任务工厂:

using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Spi;
using System;

namespace MyQuartz
{
    public class MyJobFactory : IJobFactory
    {
        private readonly IServiceProvider _serviceProvider;

        public MyJobFactory(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }

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

        public void ReturnJob(IJob job)
        {
            var disposable = job as IDisposable;
            disposable?.Dispose();

        }
    }
}

 

最后是Main方法

using System;
using Microsoft.Extensions.DependencyInjection;
using IMySql;
using MySqlServerTest;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using System.Threading.Tasks;

namespace MyQuartz
{
    class Program
    {
        static async Task Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddScoped<IMySqlInterface, SqlServerHelpr>();

            //替换成自定义的任务工厂
            services.AddSingleton<IJobFactory, MyJobFactory>();
            services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
            //任务类也需要注册到容器
            services.AddSingleton<MyJob>();

            var provider = services.BuildServiceProvider();var _jobFactory = provider.GetService<IJobFactory>();
            var _schedulerFactory = provider.GetService<ISchedulerFactory>();

            IScheduler scheduler = await _schedulerFactory.GetScheduler();
            //关键在于这里,替换掉调度器默认的任务工厂
            scheduler.JobFactory = _jobFactory;
            await scheduler.Start();

            //创建一个MyJob任务,一秒跑一次
            IJobDetail myJob = JobBuilder.Create<MyJob>()
                .WithIdentity("myJob", "group1")
                .Build();

            ITrigger myTrigger = TriggerBuilder.Create()
                .WithIdentity("myTrigger", "group1")
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(1)
                    .RepeatForever())
            .Build();

            await scheduler.ScheduleJob(myJob, myTrigger);

            Console.ReadKey();
        }
    }
}

要注意的点都用注释说明,简单明了。

最终效果

 

 

本文参考了

https://www.cnblogs.com/yanglang/p/12071336.html

https://www.cnblogs.com/dayang12525/p/13083026.html

 
posted @ 2021-09-29 16:06  exxxxia  阅读(1710)  评论(1编辑  收藏  举报