using Bowin.Common.Utility; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Quartz; using Quartz.Impl; using Quartz.Spi; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; namespace Bowin.Common.Scheduler { public static class Scheduler { private static List jobList { get; set; } private static Dictionary> schedulerJobDic { get; set; } //private static IServiceCollection ServiceCollection; #region 配置 public static void AddQuartz(this IServiceCollection services, Assembly assembly = null) { services.AddSingleton(); //ServiceCollection = services; ScheduleAllJob(assembly); jobList.ForEach(jobType => services.Add(new ServiceDescriptor(jobType, jobType, ServiceLifetime.Scoped))); services.AddSingleton(provider => { var schedulerFactory = new StdSchedulerFactory(); var scheduler = schedulerFactory.GetScheduler().Result; scheduler.JobFactory = provider.GetService(); scheduler.Start(); return scheduler; }); //Scheduler.StartJobs(); } #endregion public static void ScheduleAllJob(Assembly assembly = null) { if (assembly == null) { assembly = Assembly.GetEntryAssembly(); } jobList = assembly.GetTypes().Where(x => x.GetInterfaces().Any(i => i.Name == "IJob")) .ToList(); schedulerJobDic = new Dictionary>(); foreach (var job in jobList) { var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); string intervalStr = configuration.GetSection("Scheduler").GetSection("Jobs").GetValue(job.FullName + ".Interval"); IJobDetail jobIns = JobBuilder.Create(job).WithIdentity(job.FullName, job.Namespace).Build(); ITrigger triggerIns; int interval; if (!int.TryParse(intervalStr, out interval)) { string cronStr = configuration.GetSection("Scheduler").GetSection("Jobs").GetValue(job.FullName + ".cron"); if (string.IsNullOrEmpty(cronStr)) { continue; } else { triggerIns = TriggerBuilder.Create() .WithIdentity(job.FullName + "_Trigger", job.Namespace) .StartNow() .WithCronSchedule(cronStr).Build(); } } else { triggerIns = TriggerBuilder.Create() .WithIdentity(job.FullName + "_Trigger", job.Namespace) .StartNow() .WithSimpleSchedule(x => x.WithIntervalInSeconds(interval).RepeatForever()).Build(); } var triggerSet = new HashSet(); triggerSet.Add(triggerIns); schedulerJobDic.Add(jobIns, triggerSet); } } public static void StartSchedulerJobs(this IApplicationBuilder app) { var scheduler = new StdSchedulerFactory().GetScheduler().Result; scheduler.JobFactory = HttpHelper.GetService(); //scheduler.JobFactory = ServiceCollection.BuildServiceProvider().GetService(); scheduler.ScheduleJobs(schedulerJobDic, true); scheduler.Start(); } } public class QuartzFactory : IJobFactory { private readonly IServiceProvider _serviceProvider; public QuartzFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { var jobDetail = bundle.JobDetail; var job = (IJob)_serviceProvider.GetService(jobDetail.JobType); return job; } public void ReturnJob(IJob job) { var disposable = job as IDisposable; disposable?.Dispose(); } } }