using JSMachine.WMS.Common; using JSMachine.WMS.Infrastructure.Enums; using JSMachine.WMS.Job.Enum; using JSMachine.WMS.Job.JobAttributes; using Microsoft.AspNetCore.Builder; using Quartz; using Quartz.Impl; using Quartz.Impl.Matchers; using System.Collections.Specialized; using System.Reflection; namespace JSMachine.WMS.Job { /// /// Quartz 作业调度引擎,根据 JobAttribute 自动发现并注册作业。 /// public static class JobEngine { /// /// 启动 Quartz 调度器,并按作业属性创建周期触发器。 /// 作业执行由 Quartz 管理,调用方无需等待单次作业完成。 /// public async static void UseAllJobs(this IApplicationBuilder app) { List<(Type, JobAttribute)> tuples = ResolveAllJobTypes(); ISchedulerFactory schedulerFactory = new StdSchedulerFactory(); IScheduler scheduler = await schedulerFactory.GetScheduler(); await scheduler.Start(); // 每个作业独立创建 JobDetail 和 Trigger,避免不同作业共享调度配置。 tuples?.ForEach(async tuple => { IJobDetail jobDetail = JobBuilder .Create(tuple.Item1) .WithIdentity(tuple.Item2.Name, tuple.Item2.Group) .Build(); TriggerBuilder triggerBuilder = TriggerBuilder .Create() .WithIdentity($"{tuple.Item2.Name}Trigger", tuple.Item2.Group); if (tuple.Item2.ScheduleType == ScheduleType.Simple) { triggerBuilder.WithSimpleSchedule(p => { p.WithInterval(TimeSpan.FromMilliseconds(tuple.Item2.IntervalMilliSeconds)); if (tuple.Item2.RepeatCount > 0) { p.WithRepeatCount(tuple.Item2.RepeatCount); } else { p.RepeatForever(); } }); } ITrigger trigger = triggerBuilder.Build(); await scheduler.ScheduleJob(jobDetail, trigger); }); } private static List<(Type, JobAttribute)> ResolveAllJobTypes() { Assembly assembly = typeof(JobEngine).Assembly; //获取所有类 Type[] jobTypes = assembly .GetTypes() .Where(t => t.IsDefined(typeof(JobAttribute), false) && typeof(IJob).IsAssignableFrom(t)) .ToArray(); List<(Type, JobAttribute)> tuples = new(); //获取类定义的 foreach (Type jobType in jobTypes) { object[] attrs = jobType.GetCustomAttributes(typeof(JobAttribute), false); if (attrs.Length > 0) { foreach (var attr in attrs) { if (attr is JobAttribute attribute) { tuples.Add((jobType, attribute)); } } } } return tuples; } } }