编辑
2022-10-13
我当开发
00

在做定时任务模块,将原有的方法,作为定时任务执行,由前台配置定时的时间,这里使用的是特性,就是给方法脑袋上加个[SysTask] ,在系统启动后 读取全部带SysTask特性的方法,这样就可以在前台展示了。 这里需要 遍历当前解决方案所有的程序集的所有方法,得到包括SysTask特性的方法,然后实例化该类,执行方法;

就是一个遍历, 这里直接写出

public static class AssemblyHelper { /// <summary> /// 返回 指定特性的 方法 /// </summary> /// <typeparam name="T">特性</typeparam> /// <returns> /// <para>context 当前类</para> /// <para>methodInfo 当前方法</para> /// <para>attrdata 当前特性</para> /// <para>constructorArguments 特性的参数</para> /// <para>namedArguments 特性的属性</para> /// </returns> public static IEnumerable<( Type context, MethodInfo methodInfo, CustomAttributeData? attrdata, IList<CustomAttributeTypedArgument>? constructorArguments, IList<CustomAttributeNamedArgument>? namedArguments)> GetAttributeMethodInfo<T>() { var listassembly = GetAllAssembly(); var listtypes = listassembly.AsParallel() .Where(m => m!.FullName!.StartsWith("HD")).Select(m => m.GetTypes()).SelectMany(m => m); foreach (var context in listtypes) { var listmethodInfo = context.GetMethods().AsParallel() .Where(t => t.GetCustomAttributes(typeof(T), false).Length > 0); foreach (var methodInfo in listmethodInfo) { var attrdata = methodInfo.CustomAttributes.Where(t => t.AttributeType == typeof(T)) .FirstOrDefault(); yield return (context, methodInfo, attrdata, attrdata?.ConstructorArguments, attrdata?.NamedArguments); } } } /// <summary> /// 得到所有程序集 /// </summary> /// <returns></returns> public static IEnumerable<Assembly> GetAllAssembly() { var refAssembyNames = Assembly.GetExecutingAssembly().GetReferencedAssemblies(); foreach (var asslembyNames in refAssembyNames) { Assembly.Load(asslembyNames); } return AppDomain.CurrentDomain.GetAssemblies(); } }

使用遍历

/// <summary> /// 得到所有的任务 /// </summary> public static void GetAllTasks() { AssemblyHelper.GetAttributeMethodInfo<SysTaskAttribute>() .ToList().ForEach(res => { var context = res.context;//类 var methodInfo = res.methodInfo;//方法 var args = res.constructorArguments;//特性传的参数 }); }

可以注意一下最后两个参数 ,一个是 ConstructorArguments,一个是 NamedArguments

如果特性是这么写的

[SysTask(taskGUID, "更新数据源")] public static void Update(string SourceKey) { }

就是普通的重载,那么使用 ConstructorArguments 就可以拿到了,是一个集合 0,1,2,3 这么拿,

如果你的特性这么写

[AttributeUsage(AttributeTargets.Method)] public class SysTaskAttribute : Attribute { public string key { get; set; } }

没有重载,AttributeTargets.Method 是属性可以当参数的意思 那么特性可以这样用

[SysTask(key = taskGUID)] public static void Update(string SourceKey) { }

没有重载时 ConstructorArguments 就拿不到了,要用 最后一个参数就是 NamedArguments

---分割线---

那么如何实例化方法调用,并且传参呢,先下班,想起来补;

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:没想好

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!