动态执行方法

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
    }
}

  

posted @ 2020-04-10 14:07  谁说程序猿很猥琐  阅读(231)  评论(0编辑  收藏  举报