using NCC;
using NCC.Dependency;
using NCC.Extensions;
using NCC.TaskScheduler;
using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace Microsoft.Extensions.DependencyInjection
{
///
/// 任务调度类服务拓展
///
[SuppressSniffer]
public static class TaskSchedulerServiceCollectionExtensions
{
///
/// 添加任务调度服务
///
///
///
public static IServiceCollection AddTaskScheduler(this IServiceCollection services)
{
// 查找所有贴了 [SpareTime] 特性的方法,并且含有一个参数,参数为 SpareTimer 类型
var taskMethods = App.EffectiveTypes
// 查询符合条件的任务类型
.Where(u => u.IsClass && !u.IsInterface && !u.IsAbstract && typeof(ISpareTimeWorker).IsAssignableFrom(u))
// 查询符合条件的任务方法
.SelectMany(u =>
u.GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(m => m.IsDefined(typeof(SpareTimeAttribute), false)
&& m.GetParameters().Length == 2
&& m.GetParameters()[0].ParameterType == typeof(SpareTimer)
&& m.GetParameters()[1].ParameterType == typeof(long))
.GroupBy(m => m.DeclaringType));
if (!taskMethods.Any()) return services;
// 遍历所有的 Worker
foreach (var item in taskMethods)
{
if (!item.Any()) continue;
// 创建任务对象
var typeInstance = Activator.CreateInstance(item.Key);
foreach (var method in item)
{
// 判断是否是异步方法
var isAsyncMethod = method.IsAsync();
// 创建委托类型
var action = Delegate.CreateDelegate(isAsyncMethod ? typeof(Func) : typeof(Action), typeInstance, method.Name);
// 获取所有任务特性
var spareTimeAttributes = method.GetCustomAttributes();
// 注册任务
foreach (var spareTimeAttribute in spareTimeAttributes)
{
switch (spareTimeAttribute.Type)
{
// 执行间隔任务
case SpareTimeTypes.Interval:
// 执行一次
if (spareTimeAttribute.DoOnce)
{
if (isAsyncMethod)
{
SpareTime.DoOnce(spareTimeAttribute.Interval, (Func)action, spareTimeAttribute.WorkerName, spareTimeAttribute.Description, spareTimeAttribute.StartNow, executeType: spareTimeAttribute.ExecuteType);
}
else
{
SpareTime.DoOnce(spareTimeAttribute.Interval, (Action)action, spareTimeAttribute.WorkerName, spareTimeAttribute.Description, spareTimeAttribute.StartNow, executeType: spareTimeAttribute.ExecuteType);
}
}
// 不间断执行
else
{
if (isAsyncMethod)
{
SpareTime.Do(spareTimeAttribute.Interval, (Func)action, spareTimeAttribute.WorkerName, spareTimeAttribute.Description, spareTimeAttribute.StartNow, executeType: spareTimeAttribute.ExecuteType);
}
else
{
SpareTime.Do(spareTimeAttribute.Interval, (Action)action, spareTimeAttribute.WorkerName, spareTimeAttribute.Description, spareTimeAttribute.StartNow, executeType: spareTimeAttribute.ExecuteType);
}
}
break;
// 执行 Cron 表达式任务
case SpareTimeTypes.Cron:
if (isAsyncMethod)
{
SpareTime.Do(spareTimeAttribute.CronExpression, (Func)action, spareTimeAttribute.WorkerName, spareTimeAttribute.Description, spareTimeAttribute.StartNow, cronFormat: spareTimeAttribute.CronFormat == default ? default : (CronFormat)spareTimeAttribute.CronFormat, executeType: spareTimeAttribute.ExecuteType);
}
else
{
SpareTime.Do(spareTimeAttribute.CronExpression, (Action)action, spareTimeAttribute.WorkerName, spareTimeAttribute.Description, spareTimeAttribute.StartNow, cronFormat: spareTimeAttribute.CronFormat == default ? default : (CronFormat)spareTimeAttribute.CronFormat, executeType: spareTimeAttribute.ExecuteType);
}
break;
default:
break;
}
}
}
}
return services;
}
}
}