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