C# 反射 + Quartz,实现流程处理
场景:
前不久,公司里项目经理要求我实现流程处理,比如,用户可以定义一个定时任务,每周一查看报表。定时任务很简单,用Quartz可以实现,但是用户自己选择报表就比较麻烦,因为系统的不同模块的生成报表的函数不一样,于是有了这样的想法:传入一个方法名和方法的输入参数,就可以调用该方法。
实现:
这里主要用的是反射的方法。用户要传入方法名和方法参数,我们就需要先写函数返回这些信息,最后再包装一下返回给用户。
获取某一程序集下所有类:(对我来说,获取当前程序集下的类就够了,要获取其他程序集或dll的,请查询其他资料)
public List<string> GetClass(string assembyName = null)
{
Assembly asm = Assembly.GetExecutingAssembly();
var allclass = asm.ExportedTypes.ToList();
return allclass.Select(u => u.Name).ToList();
}
获取某一个类中所有的方法,主要用到GetMethods()的方法:
public List<string> GetMethod(Type type,string assembyName = null)
{
// 测试获取指定类的方法,去除自带的GetType方法
List<MethodInfo> methods = type.GetMethods().Where(u=>u.IsVirtual == false)
.Where(u => !u.Name.Contains("GetType")).ToList();
return methods.Select(u => u.Name).ToList();
}
获取某一个方法的传入参数类型,我是通过把method直接tostring(),来解析出输入类的名称的,应该有其他方法可以拿到输入类的名称:
public List<string> GetParameter(MethodInfo methodInfo, Assembly assembly)
{
// 由方法获取输入类,创建类
var method_FullName = methodInfo.ToString();
// 方法中找不到input类的信息,只能从fullname中解析出来
Regex reg = new Regex(@"(?is)(?<=\()(.*)(?=\))");
Match m = reg.Match(method_FullName);
string inputName = m.Value.Split(".").Last();
Type input_class = assembly.ExportedTypes.Where(u => u.Name.Contains(inputName)).First();
PropertyInfo[] propertyInfos = input_class.GetProperties();
List<string> result = new List<string>();
foreach ( var item in propertyInfos )
{
var returnType = item.GetGetMethod().ReturnType;
var name = returnType.ToString();
result.Add(name);
}
return result;
}
可以获取输入类的属性类型。
创建实例,并执行方法:
如果是用放射的方式实例化类,很麻烦的是类的构造函数中存在依赖关系。于是我才用依赖注入中获取类的方法。
首先,创建一个IServiceProvider的静态类来获取系统依赖注入中的所有服务,再main函数中进行获取和赋值:
public static class ServiceHelper
{
public static IServiceProvider Instance { get; set; } }
在main中获取依赖注入:
public static void Main(string[] args)
{
var webhost = CreateHostBuilder(args).Build();
using ( var scope = webhost.Services.CreateScope() )
{
ServiceHelper.Instance = webhost.Services;
} webhost.Run();
}
这样,就可以避免依赖关系,直接拿依赖注入中的类来反射方法,并执行:
// 获取依赖注入中类
var api = ServiceHelper.Instance.GetService(do_class);
这里的do_class是一个Type。
最后,是使用invoke来执行方法:
PropertyInfo[] propertyInfos = input_class.GetProperties();
Object Args = asm.CreateInstance(input_class.FullName);
foreach ( var item in propertyInfos )
{
var returnType = item.GetGetMethod().ReturnType;
var name = returnType.ToString();
// 匹配类型
if ( name.ToLower().Contains("string") )
{
item.SetValue(Args, "test");
}
else if ( name.ToLower().Contains("int") )
{
item.SetValue(Args, 1);
}
}
// 模拟某方法进行执行
object[] inputArgs = new object[] { Args };
try
{
var result = method.Invoke(api, inputArgs);
}
catch ( Exception ex)
{
Console.WriteLine(ex.Message);
}
这里的Args是通过input类获取的参数类型而设置的实例对象,由于invoke的参数类型为objetc[],所以需要再包装一层。
method是要调用的方法,api是该类的实例,从依赖注入中获取。
最后:
最后就是Quartz的配合,这里就不写了,可以通过JobDataMap来传递参数。再结合HTTP client,可以实现基本流程处理。既可以调用内部函数,也可以http调用接口。
C# 反射 + Quartz,实现流程处理的更多相关文章
- Quartz系列(一):基础介绍
新建一个.NET Core控制台项目,NuGet引用Quartz引用. class Program { static void Main(string[] args) { var task = Tas ...
- quartz (从原理到应用)详解篇(转)
一.Quartz 基本介绍 1.1 Quartz 概述 1.2 Quartz特点 1.3 Quartz 集群配置 二.Quartz 原理及流程 2.1 quartz基本原理 2.2 quartz启动流 ...
- MFC的消息反射机制
1.消息反射解释: 父窗口将子窗口发给它的通知消息,首先反射回子窗口进行处理(即给子窗口一个机会,让子窗口处理此消息),这样通知消息就有机会能被子窗口自身进行处理. 2.MFC中引入消息反射的原因: ...
- JAVAEE——BOS物流项目13:Quartz概述、创建定时任务、使用JavaMail发送邮件、HighCharts概述、实现区域分区分布图
1 学习计划 1.Quartz概述 n Quartz介绍和下载 n 入门案例 n Quartz执行流程 n cron表达式 2.在BOS项目中使用Quartz创建定时任务 3.在BOS项目中使用Jav ...
- 【java基础】从反射开始(Reflection)
Java学习笔记 https://github.com/SnailDev/java-learning 和我一起启程... 反射(Reflection) 定义 在运行状态中, 对于任意的一个类,都能够知 ...
- Quartz原理解密
Quartz原理解密 Author: Dorae Date:2018年7月17日15:55:02 转载请注明出处 一.quartz概述 quartz是一个用java实现的开源任务调度框架,可以用来创建 ...
- Android 插件化开发(一):Java 反射技术介绍
写在前面:学习插件化开发推荐书籍<Android 插件化开发指南>,本系列博客所整理知识部分内容出自此书. 在之前的项目架构的博文中,我们提到了项目插件化架构,提到插件化架构不得不提的到J ...
- Quartz入门以及相关表达式使用
目的: 1.Quartz简介及应用场景 2.Quartz简单触发器 SimpleTrigger介绍 3.Quartz表达式触发器CronTirgger介绍 4.Quartz中参数传递 5.Spring ...
- spring整合Quartz框架过程,大家可以参考下
这篇文章详细介绍了spring集成quartz框架流程,通过示例代码进行了详细说明,对学习或任务有参考学习价值,并可供需要的朋友参考. 1.quartz框架简介(m.0831jl.com) quart ...
随机推荐
- Discuz ML RCE漏洞
1.漏洞描述 Discuz国际版漏洞存在于cookie的language可控并且没有严格过滤,导致可以远程代码执行. 2.产生原因:Discuz!ML 系统对cookie中的l接收的language参 ...
- Java流程控制06——break continue
- CVE-2020-1472
主要记下流程 我擦,这个洞mimikatz也可以搞 但是我就不记录了 检验漏洞是否存在 https://github.com/SecuraBV/CVE-2020-1472 先获取域控信息 然后测试能否 ...
- 做Android开发怎么才能不被淘汰?
1.Jetpack架构组件从入门到精通 Android Jetpack - Navigation Android Jetpack - Data Binding Android Jetpack - Vi ...
- 30K入职腾讯,全靠这份606页的Android面试指南
前言 光阴似箭,日月如梭,时间真的过得飞快. 加上实习,从事 Android 开发,差不多有 5 年了.在上家公司职务.薪酬感觉已经到达了天花板,没有上升的余地.而且在这家公司过于安逸了,想换个有挑战 ...
- MVVM窗体show的弹窗事件
RestMatCutWin restMatCutWindow;//定义一个窗体的全局变量 private void RestMatCutWinExecute() { if (restMatCutWin ...
- AQS源码分析看这一篇就够了
好了,我们来开始今天的内容,首先我们来看下AQS是什么,全称是 AbstractQueuedSynchronizer 翻译过来就是[抽象队列同步]对吧.通过名字我们也能看出这是个抽象类 而且里面定 ...
- 两个线程交叉打印一个打印A一个打印B 循环打印?
public static Object obj1 = new Object(); public static void printAB(){ Thread t1 = new Thread(() -& ...
- Anaconda Pycharm 是怎么个事儿?
前言 许多人学习Python的经历可能很相似,写程序没有问题,最后却被各种环境困扰. 不论你是Python小白,还是学习Python有一段时间了.都可以认真的看一下ヾ(≧▽≦*)o 这篇文章让你对An ...
- wpf 自定义 RadioButton.
<Style TargetType="RadioButton" x:Key="nav"> <Setter Property="Tem ...