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