using System.Linq.Expressions; using System.Reflection; using Dlhis.ScheduledTask.Attributes; using Hangfire; using Hangfire.Common; using Kurisu.AspNetCore.Startup; using Kurisu.AspNetCore.Utils.Extensions; namespace Dlhis.ScheduledTask.Packs; public class JobPack : BaseAppPack { public override int Order => 999; public override void Invoke(IServiceProvider serviceProvider) { var logger = serviceProvider.GetService>(); var jobs = Assembly.GetEntryAssembly().GetTypes() .Where(x => x.IsAssignableTo(typeof(BaseJob)) && x != typeof(BaseJob)) .Where(x => x.IsDefined(typeof(RecurringJobAttribute))) .ToList(); var setJob = typeof(Job).GetMethod(nameof(Job.FromExpression), BindingFlags.NonPublic | BindingFlags.Static, new[] { typeof(LambdaExpression), typeof(Type), typeof(string) }); var m = (Lazy)typeof(RecurringJob).GetField("Instance", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); (jobs.Select(job => job.GetCustomAttribute().UniqueJobKey).Distinct().Count() != jobs.Count).ThrowIfTrue("任务key重复"); logger.LogDebug("一共获取{count}个调度任务", jobs.Count); foreach (var job in jobs) { var recurringSetting = job.GetCustomAttribute()!; recurringSetting.Cron.IsEmpty().ThrowIfTrue(job.Name + "尚未定义Cron"); var parameterExpression = Expression.Parameter(job); var todo = job.GetMethod(nameof(BaseJob.TodoAsync)); var todoExp = Expression.Call(parameterExpression, todo); var nJob = (Job)setJob.Invoke(null, new object[] { Expression.Lambda(todoExp), job, recurringSetting.Queue }); m.Value.AddOrUpdate(recurringSetting.UniqueJobKey, nJob, recurringSetting.Cron, new RecurringJobOptions { TimeZone = TimeZoneInfo.Local }); } } }