动态执行方法
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace NNF2.Damon.Utilitily.FunctionHelper { /// <summary> /// <info 作者='hnzheng' 日期='2018-06-02'></info> /// IFuncOperateService /// </summary> public interface IFuncOperateService { /// <summary> /// 执行一个方法 /// </summary> /// <typeparam name="T">当前对象</typeparam> /// <param name="methodName"></param> /// <param name="parameters">此对象数组在数量、顺序和类型方面与要调用的方法或构造函数的参数相同</param> /// <param name="parametersTypes">参数的类型,默认defaultPubicMethod时,parametersTypes为Null</param> /// <param name="defaultPubicMethod">是否只获取公共方法</param> /// <returns>返回执行结果</returns> Task<ExecuteResult> Excute<T>(String methodName, object[] parameters, Type[] parametersTypes, Boolean defaultPubicMethod = false) where T : class; /// <summary> /// /// </summary> /// <param name="assemblynName">程序集的名称</param> /// <param name="classFullName">对象的全称,加对应的程序集名称</param> /// <param name="methodName">方法名称</param> /// <param name="parameters">参数</param> /// <param name="parametersTypes">参数类型,如果默认defaultPubicMethod ,为null</param> /// <param name="defaultPubicMethod">是否只获取公共方法</param> /// <returns>返回执行结果</returns> Task<ExecuteResult> Excute(String assemblynName, String classFullName, String methodName, Object[] parameters, Type[] parametersTypes, Boolean defaultPubicMethod = false); /// <summary> /// /// </summary> /// <param name="assemblyFilePath">程序集的详细路径</param> /// <param name="assemblynName">程序集的名称</param> /// <param name="classFullName">对象的名称</param> /// <param name="methodName">方法的名称</param> /// <param name="parameters">参数</param> /// <param name="parametersTypes">参数类型,如果默认defaultPubicMethod ,为null</param> /// <param name="defaultPubicMethod">是否只获取公共方法</param> /// <returns>返回执行结果</returns> Task<ExecuteResult> Excute(String assemblyFilePath, String assemblynName, String classFullName, String methodName, Object[] parameters, Type[] parametersTypes, Boolean defaultPubicMethod = false); /// <summary> /// 根据程序集的名称,返回Assembly的list /// </summary> /// <param name="AssemblyNames">程序集名称</param> /// <returns></returns> IEnumerable<Assembly> LoadAssemblys(IEnumerable<String> AssemblyNames); /// <summary> /// 将value按照对应的type进行转换 /// </summary> /// <param name="obj">转化后的值</param> /// <param name="type">转化类型</param> /// <param name="value">待转换的值</param> void GetParameterValue(ref Object obj, Type type, Object value); /// <summary> /// 获取一个参数列表 /// </summary> /// <param name="tuples">待转化的类型和对应的值</param> /// <returns>转化后的参数列表</returns> Object[] GetParameterValues(IEnumerable<Tuple<Type, object>> tuples); /// <summary> /// 获取method的参数信息 /// </summary> /// <typeparam name="T">当前类</typeparam> /// <param name="methodName">方法名称</param> /// <returns>参数信息</returns> ParameterInfo[] GetParameters<T>(String methodName) where T : class; /// <summary> /// 获取method的参数信息 /// </summary> /// <param name="AssemblyName">程序集名称</param> /// <param name="ClassFullName">clas的完整名称</param> /// <param name="methodName">方法名称</param> /// <returns>参数信息</returns> ParameterInfo[] GetParameters(String assemblyName, String ClassFullName, String methodName); /// <summary> /// 获取带有该属性的类 /// </summary> /// <typeparam name="T">属性</typeparam> /// <param name="Assembly">程序集</param> /// <returns></returns> IEnumerable<Type> GetClass<T>(Assembly assembly) where T : Attribute; /// <summary> /// 根据类型的Name转化类型 /// </summary> /// <param name="obj"></param> /// <param name="typeName"></param> /// <param name="value"></param> void GetParameterValue(ref Object obj, string typeName, Object value); } }
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using System.Web; namespace NNF2.Damon.Utilitily.FunctionHelper { public class FuncOperateService : IFuncOperateService { private static FuncOperateService _funcOperateService = null; public static FuncOperateService CreateInstance() { if (_funcOperateService == null) _funcOperateService = new FuncOperateService(); return _funcOperateService; } private static readonly Object obj = new Object(); public async Task<ExecuteResult> Excute<T>(String methodName, Object[] parameters, Type[] parametersTypes, Boolean defaultPubicMethod = false) where T : class { return await Excute(typeof(T), methodName, parameters, parametersTypes, defaultPubicMethod); } public Task<ExecuteResult> Excute(String assemblynName, String classFullName, String methodName, Object[] parameters, Type[] parametersTypes, Boolean defaultPubicMethod = false) { try { Assembly assembly = Assembly.Load(new AssemblyName(assemblynName)); if (assembly == null) throw new ArgumentNullException(String.Format("Can't load Assembly {0}", assemblynName)); Type type = assembly.GetType(classFullName); if (type == null) throw new ArgumentNullException(String.Format("Can't get type,Assembly {0}", assemblynName)); return Excute(type, methodName, parameters, parametersTypes, defaultPubicMethod); } catch { throw new Exception(String.Format("Can't load Assembly {0}", assemblynName)); } } public async Task<ExecuteResult> Excute(String assemblyFilePath, String assemblynName, String classFullName, String methodName, Object[] parameters, Type[] parametersTypes, Boolean defaultPubicMethod = false) { try { //Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + "Bin/App_Code.dll"); //加载程序集(dll文件地址),使用Assembly类 Assembly assembly = Assembly.LoadFile(assemblyFilePath); if (assembly == null) throw new ArgumentNullException(String.Format("Can't load Assembly {0}", assemblyFilePath)); Type type = assembly.GetType(classFullName); if (type == null) throw new ArgumentNullException(String.Format("Can't get type,Assembly {0}", assemblyFilePath)); return await Excute(type, methodName, parameters, parametersTypes, defaultPubicMethod); } catch { throw new Exception(String.Format("Can't load Assembly {0}", assemblynName)); } } public IEnumerable<Assembly> LoadAssemblys(IEnumerable<String> AssemblyNames) { foreach (string assembly in AssemblyNames) { yield return Assembly.Load(assembly); } } public virtual void GetParameterValue(ref Object obj, Type type, Object value) { try { if (type == typeof(System.String)) obj = value; else if (type == typeof(System.Int32)) obj = Convert.ToInt32(value); else if (type == typeof(System.DateTime)) obj = Convert.ToDateTime(value); else if (type == typeof(System.Decimal)) obj = Convert.ToDecimal(value); else if (type == typeof(System.Boolean)) obj = Convert.ToBoolean(value); else if (type == typeof(System.Double)) obj = Convert.ToDouble(value); else if (type == typeof(System.Single)) obj = Convert.ToSingle(value); else throw new ArgumentOutOfRangeException(String.Format("Out of range,Please check the value type,detail:obj:{0},Type:{1},Value:{2}", obj, type, value)); } catch { throw new ArgumentException(String.Format("Can't convet {0} to {1}", value, type)); } } public virtual void GetParameterValue(ref Object obj, string typeName, Object value) { try { if (typeName == "System.String") obj = value; else if (typeName == "System.Int32") obj = Convert.ToInt32(value); else if (typeName == "System.DateTime") obj = Convert.ToDateTime(value); else if (typeName == "System.Decimal") obj = Convert.ToDecimal(value); else if (typeName == "System.Boolean") obj = Convert.ToBoolean(value); else if (typeName == "System.Double") obj = Convert.ToDouble(value); else if (typeName == "System.Single") obj = Convert.ToSingle(value); else throw new ArgumentOutOfRangeException(String.Format("Out of range,Please check the value type,detail:obj:{0},Type:{1},Value:{2}", obj, typeName, value)); } catch { throw new ArgumentException(String.Format("Can't convet {0} to {1}", value, typeName)); } } public virtual Object[] GetParameterValues(IEnumerable<Tuple<Type, object>> tuples) { Object[] obj = new Object[tuples.Count()]; int i = 0; foreach (var item in tuples) { GetParameterValue(ref obj[i], item.Item1, item.Item2); i++; } return obj; } public virtual IEnumerable<Type> GetClass<T>(Assembly assembly) where T : Attribute { try { IList<Type> newTypes = new List<Type>(); foreach (Type type in assembly.GetTypes()) { var attr = type.GetCustomAttributesData(); if (attr.Any() && attr.First().AttributeType == typeof(T)) newTypes.Add(type); } return newTypes; } catch (Exception ex) { throw new Exception(String.Format("Get type Failed,Detail:{0},Error{1}", "GetClass", ex)); } } public ParameterInfo[] GetParameters<T>(String methodName) where T : class { return typeof(T).GetTypeInfo().GetMethod(methodName).GetParameters(); } public ParameterInfo[] GetParameters(String assemblyName, String ClassFullName, String methodName) { try { Assembly assembly = Assembly.Load(new AssemblyName(assemblyName)); Type type = assembly.GetType(ClassFullName); return type.GetTypeInfo().GetMethod(methodName).GetParameters(); } catch { throw new Exception(String.Format("Can't load Assembly {0}", assemblyName)); } } #region private private async Task<ExecuteResult> Excute(Type type, String methodName, Object[] parameters, Type[] parametersTypes, Boolean defaultPubicMethod = false) { ExecuteResult executeResult = new ExecuteResult(); executeResult.IsSuccess = false; executeResult.ExcuteStatus = ExcuteStatus.ToExecute; MethodInfo method = defaultPubicMethod ? type.GetTypeInfo().GetMethod(methodName) : type.GetTypeInfo().GetMethod(methodName, parametersTypes); if (method == null) throw new Exception("The method can't find,Please check the assemblynNameInfo!"); lock (obj) { if (!method.IsStatic) { Object operate = Activator.CreateInstance(type); if (operate != null) { try { executeResult.ExcuteStatus = ExcuteStatus.Executing; executeResult.ReturnData = method.Invoke(operate, parameters); executeResult.ExcuteStatus = ExcuteStatus.Executed; executeResult.IsSuccess = true; } catch { throw new MethodAccessException("method operate failed"); } } else throw new ArgumentNullException("Create instance failed!"); } else { try { executeResult.ExcuteStatus = ExcuteStatus.Executing; executeResult.ReturnData = method.Invoke(null, parameters); executeResult.ExcuteStatus = ExcuteStatus.Executed; executeResult.IsSuccess = true; } catch { throw; //new MethodAccessException("Parameters mismatch,Please check the assemblynNameInfo!"); } } } executeResult.IsSuccess = true; return executeResult; } #endregion } }