初始化版本
This commit is contained in:
582
tongxin/NetWorkHelper/Helper/ReflectionHelper.cs
Normal file
582
tongxin/NetWorkHelper/Helper/ReflectionHelper.cs
Normal file
@@ -0,0 +1,582 @@
|
||||
using NetWorkHelper.IBase;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace NetWorkHelper.Helper
|
||||
{
|
||||
public static class ReflectionHelper
|
||||
{
|
||||
#region 获取类型
|
||||
/// <summary>
|
||||
/// GetType 通过完全限定的类型名来加载对应的类型。typeAndAssName如"NetWorkHelper.Filters.SourceFilter,NetWorkHelper"。
|
||||
/// 如果为系统简单类型,则可以不带程序集名称。
|
||||
/// </summary>
|
||||
public static Type GetType(string typeAndAssName)
|
||||
{
|
||||
string[] names = typeAndAssName.Split(',');
|
||||
if (names.Length < 2)
|
||||
{
|
||||
return Type.GetType(typeAndAssName);
|
||||
}
|
||||
|
||||
return ReflectionHelper.GetType(names[0].Trim(), names[1].Trim());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GetType 加载assemblyName程序集中的名为typeFullName的类型。assemblyName不用带扩展名,如果目标类型在当前程序集中,assemblyName传入null
|
||||
/// </summary>
|
||||
public static Type GetType(string typeFullName, string assemblyName)
|
||||
{
|
||||
if (assemblyName == null)
|
||||
{
|
||||
return Type.GetType(typeFullName);
|
||||
}
|
||||
|
||||
//搜索当前域中已加载的程序集
|
||||
Assembly[] asses = AppDomain.CurrentDomain.GetAssemblies();
|
||||
foreach (Assembly ass in asses)
|
||||
{
|
||||
string[] names = ass.FullName.Split(',');
|
||||
if (names[0].Trim() == assemblyName.Trim())
|
||||
{
|
||||
return ass.GetType(typeFullName);
|
||||
}
|
||||
}
|
||||
|
||||
//加载目标程序集
|
||||
Assembly tarAssem = Assembly.Load(assemblyName);
|
||||
if (tarAssem != null)
|
||||
{
|
||||
return tarAssem.GetType(typeFullName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetTypeFullName
|
||||
public static string GetTypeFullName(Type t)
|
||||
{
|
||||
return t.FullName + "," + t.Assembly.FullName.Split(',')[0];
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LoadDerivedInstance
|
||||
/// <summary>
|
||||
/// LoadDerivedInstance 将程序集中所有继承自TBase的类型实例化
|
||||
/// </summary>
|
||||
/// <typeparam name="TBase">基础类型(或接口类型)</typeparam>
|
||||
/// <param name="asm">目标程序集</param>
|
||||
/// <returns>TBase实例列表</returns>
|
||||
public static IList<TBase> LoadDerivedInstance<TBase>(Assembly asm)
|
||||
{
|
||||
IList<TBase> list = new List<TBase>();
|
||||
|
||||
Type supType = typeof(TBase);
|
||||
foreach (Type t in asm.GetTypes())
|
||||
{
|
||||
if (supType.IsAssignableFrom(t) && (!t.IsAbstract) && (!t.IsInterface))
|
||||
{
|
||||
TBase instance = (TBase)Activator.CreateInstance(t);
|
||||
list.Add(instance);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LoadDerivedType
|
||||
/// <summary>
|
||||
/// LoadDerivedType 加载directorySearched目录下所有程序集中的所有派生自baseType的类型
|
||||
/// </summary>
|
||||
/// <typeparam name="baseType">基类(或接口)类型</typeparam>
|
||||
/// <param name="directorySearched">搜索的目录</param>
|
||||
/// <param name="searchChildFolder">是否搜索子目录中的程序集</param>
|
||||
/// <param name="config">高级配置,可以传入null采用默认配置</param>
|
||||
/// <returns>所有从BaseType派生的类型列表</returns>
|
||||
public static IList<Type> LoadDerivedType(Type baseType, string directorySearched, bool searchChildFolder, TypeLoadConfig config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
config = new TypeLoadConfig();
|
||||
}
|
||||
|
||||
IList<Type> derivedTypeList = new List<Type>();
|
||||
if (searchChildFolder)
|
||||
{
|
||||
ReflectionHelper.LoadDerivedTypeInAllFolder(baseType, derivedTypeList, directorySearched, config);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReflectionHelper.LoadDerivedTypeInOneFolder(baseType, derivedTypeList, directorySearched, config);
|
||||
}
|
||||
|
||||
return derivedTypeList;
|
||||
}
|
||||
|
||||
#region TypeLoadConfig
|
||||
public class TypeLoadConfig
|
||||
{
|
||||
#region Ctor
|
||||
public TypeLoadConfig() { }
|
||||
public TypeLoadConfig(bool copyToMem, bool loadAbstract, string postfix)
|
||||
{
|
||||
this.copyToMemory = copyToMem;
|
||||
this.loadAbstractType = loadAbstract;
|
||||
this.targetFilePostfix = postfix;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CopyToMemory
|
||||
private bool copyToMemory = false;
|
||||
/// <summary>
|
||||
/// CopyToMem 是否将程序集拷贝到内存后加载
|
||||
/// </summary>
|
||||
public bool CopyToMemory
|
||||
{
|
||||
get { return copyToMemory; }
|
||||
set { copyToMemory = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LoadAbstractType
|
||||
private bool loadAbstractType = false;
|
||||
/// <summary>
|
||||
/// LoadAbstractType 是否加载抽象类型
|
||||
/// </summary>
|
||||
public bool LoadAbstractType
|
||||
{
|
||||
get { return loadAbstractType; }
|
||||
set { loadAbstractType = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TargetFilePostfix
|
||||
private string targetFilePostfix = ".dll";
|
||||
/// <summary>
|
||||
/// TargetFilePostfix 搜索的目标程序集的后缀名
|
||||
/// </summary>
|
||||
public string TargetFilePostfix
|
||||
{
|
||||
get { return targetFilePostfix; }
|
||||
set { targetFilePostfix = value; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LoadDerivedTypeInAllFolder
|
||||
private static void LoadDerivedTypeInAllFolder(Type baseType, IList<Type> derivedTypeList, string folderPath, TypeLoadConfig config)
|
||||
{
|
||||
ReflectionHelper.LoadDerivedTypeInOneFolder(baseType, derivedTypeList, folderPath, config);
|
||||
string[] folders = Directory.GetDirectories(folderPath);
|
||||
if (folders != null)
|
||||
{
|
||||
foreach (string nextFolder in folders)
|
||||
{
|
||||
ReflectionHelper.LoadDerivedTypeInAllFolder(baseType, derivedTypeList, nextFolder, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LoadDerivedTypeInOneFolder
|
||||
private static void LoadDerivedTypeInOneFolder(Type baseType, IList<Type> derivedTypeList, string folderPath, TypeLoadConfig config)
|
||||
{
|
||||
string[] files = Directory.GetFiles(folderPath);
|
||||
foreach (string file in files)
|
||||
{
|
||||
if (config.TargetFilePostfix != null)
|
||||
{
|
||||
if (!file.EndsWith(config.TargetFilePostfix))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Assembly asm = null;
|
||||
|
||||
#region Asm
|
||||
try
|
||||
{
|
||||
if (config.CopyToMemory)
|
||||
{
|
||||
byte[] addinStream = FileHelper.ReadFileReturnBytes(file);
|
||||
asm = Assembly.Load(addinStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
asm = Assembly.LoadFrom(file);
|
||||
}
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
ee = ee;
|
||||
}
|
||||
|
||||
if (asm == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endregion
|
||||
|
||||
Type[] types = asm.GetTypes();
|
||||
|
||||
foreach (Type t in types)
|
||||
{
|
||||
if (t.IsSubclassOf(baseType) || baseType.IsAssignableFrom(t))
|
||||
{
|
||||
bool canLoad = config.LoadAbstractType ? true : (!t.IsAbstract);
|
||||
if (canLoad)
|
||||
{
|
||||
derivedTypeList.Add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region SetProperty
|
||||
/// <summary>
|
||||
/// SetProperty 如果list中的object具有指定的propertyName属性,则设置该属性的值为proValue
|
||||
/// </summary>
|
||||
public static void SetProperty(IList<object> objs, string propertyName, object proValue)
|
||||
{
|
||||
object[] args = { proValue };
|
||||
foreach (object target in objs)
|
||||
{
|
||||
ReflectionHelper.SetProperty(target, propertyName, proValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetProperty(object obj, string propertyName, object proValue)
|
||||
{
|
||||
ReflectionHelper.SetProperty(obj, propertyName, proValue, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SetProperty 如果object具有指定的propertyName属性,则设置该属性的值为proValue
|
||||
/// </summary>
|
||||
public static void SetProperty(object obj, string propertyName, object proValue, bool ignoreError)
|
||||
{
|
||||
Type t = obj.GetType();
|
||||
PropertyInfo pro = t.GetProperty(propertyName);
|
||||
if ((pro == null) || (!pro.CanWrite))
|
||||
{
|
||||
if (!ignoreError)
|
||||
{
|
||||
string msg = string.Format("The setter of property named '{0}' not found in '{1}'.", propertyName, t);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#region 尝试转换类型
|
||||
try
|
||||
{
|
||||
proValue = TypeHelper.ChangeType(pro.PropertyType, proValue);
|
||||
}
|
||||
catch { }
|
||||
#endregion
|
||||
|
||||
object[] args = { proValue };
|
||||
t.InvokeMember(propertyName, BindingFlags.Public | BindingFlags.IgnoreCase |
|
||||
BindingFlags.Instance | BindingFlags.SetProperty, null, obj, args);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetProperty
|
||||
/// <summary>
|
||||
/// GetProperty 根据指定的属性名获取目标对象该属性的值
|
||||
/// </summary>
|
||||
public static object GetProperty(object obj, string propertyName)
|
||||
{
|
||||
Type t = obj.GetType();
|
||||
|
||||
return t.InvokeMember(propertyName, BindingFlags.Default | BindingFlags.GetProperty, null, obj, null);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetFieldValue
|
||||
/// <summary>
|
||||
/// GetFieldValue 取得目标对象的指定field的值,field可以是private
|
||||
/// </summary>
|
||||
public static object GetFieldValue(object obj, string fieldName)
|
||||
{
|
||||
Type t = obj.GetType();
|
||||
FieldInfo field = t.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
|
||||
if (field == null)
|
||||
{
|
||||
string msg = string.Format("The field named '{0}' not found in '{1}'.", fieldName, t);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
return field.GetValue(obj);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SetFieldValue
|
||||
/// <summary>
|
||||
/// SetFieldValue 设置目标对象的指定field的值,field可以是private
|
||||
/// </summary>
|
||||
public static void SetFieldValue(object obj, string fieldName, object val)
|
||||
{
|
||||
Type t = obj.GetType();
|
||||
FieldInfo field = t.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetField | BindingFlags.Instance);
|
||||
if (field == null)
|
||||
{
|
||||
string msg = string.Format("The field named '{0}' not found in '{1}'.", fieldName, t);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
field.SetValue(obj, val);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CopyProperty
|
||||
/// <summary>
|
||||
/// CopyProperty 将source中的属性的值赋给target上同名的属性
|
||||
/// 使用CopyProperty可以方便的实现拷贝构造函数
|
||||
/// </summary>
|
||||
public static void CopyProperty(object source, object target)
|
||||
{
|
||||
ReflectionHelper.CopyProperty(source, target, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CopyProperty 将source中的属性的值赋给target上想匹配的属性,匹配关系通过propertyMapItemList确定
|
||||
/// </summary>
|
||||
public static void CopyProperty(object source, object target, IList<MapItem> propertyMapItemList)
|
||||
{
|
||||
Type sourceType = source.GetType();
|
||||
Type targetType = target.GetType();
|
||||
PropertyInfo[] sourcePros = sourceType.GetProperties();
|
||||
|
||||
if (propertyMapItemList != null)
|
||||
{
|
||||
foreach (MapItem item in propertyMapItemList)
|
||||
{
|
||||
object val = ReflectionHelper.GetProperty(source, item.Source);
|
||||
ReflectionHelper.SetProperty(target, item.Target, val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (PropertyInfo sourceProperty in sourcePros)
|
||||
{
|
||||
if (sourceProperty.CanRead)
|
||||
{
|
||||
object val = ReflectionHelper.GetProperty(source, sourceProperty.Name);
|
||||
ReflectionHelper.SetProperty(target, sourceProperty.Name, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetAllMethods、SearchMethod
|
||||
/// <summary>
|
||||
/// GetAllMethods 获取接口的所有方法信息,包括继承的
|
||||
/// </summary>
|
||||
public static IList<MethodInfo> GetAllMethods(params Type[] interfaceTypes)
|
||||
{
|
||||
foreach (Type interfaceType in interfaceTypes)
|
||||
{
|
||||
if (!interfaceType.IsInterface)
|
||||
{
|
||||
throw new Exception("Target Type must be interface!");
|
||||
}
|
||||
}
|
||||
|
||||
IList<MethodInfo> list = new List<MethodInfo>();
|
||||
foreach (Type interfaceType in interfaceTypes)
|
||||
{
|
||||
ReflectionHelper.DistillMethods(interfaceType, ref list);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void DistillMethods(Type interfaceType, ref IList<MethodInfo> methodList)
|
||||
{
|
||||
foreach (MethodInfo meth in interfaceType.GetMethods())
|
||||
{
|
||||
bool isExist = false;
|
||||
foreach (MethodInfo temp in methodList)
|
||||
{
|
||||
if ((temp.Name == meth.Name) && (temp.ReturnType == meth.ReturnType))
|
||||
{
|
||||
ParameterInfo[] para1 = temp.GetParameters();
|
||||
ParameterInfo[] para2 = meth.GetParameters();
|
||||
if (para1.Length == para2.Length)
|
||||
{
|
||||
bool same = true;
|
||||
for (int i = 0; i < para1.Length; i++)
|
||||
{
|
||||
if (para1[i].ParameterType != para2[i].ParameterType)
|
||||
{
|
||||
same = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (same)
|
||||
{
|
||||
isExist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isExist)
|
||||
{
|
||||
methodList.Add(meth);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Type superInterfaceType in interfaceType.GetInterfaces())
|
||||
{
|
||||
ReflectionHelper.DistillMethods(superInterfaceType, ref methodList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// SearchGenericMethodInType 搜索指定类型定义的泛型方法,不包括继承的。
|
||||
/// </summary>
|
||||
public static MethodInfo SearchGenericMethodInType(Type originType, string methodName, Type[] argTypes)
|
||||
{
|
||||
foreach (MethodInfo method in originType.GetMethods())
|
||||
{
|
||||
if (method.ContainsGenericParameters && method.Name == methodName)
|
||||
{
|
||||
bool succeed = true;
|
||||
ParameterInfo[] paras = method.GetParameters();
|
||||
if (paras.Length == argTypes.Length)
|
||||
{
|
||||
for (int i = 0; i < paras.Length; i++)
|
||||
{
|
||||
if (!paras[i].ParameterType.IsGenericParameter) //跳过泛型参数
|
||||
{
|
||||
if (paras[i].ParameterType.IsGenericType) //如果参数本身就是泛型类型,如IList<T>
|
||||
{
|
||||
if (paras[i].ParameterType.GetGenericTypeDefinition() != argTypes[i].GetGenericTypeDefinition())
|
||||
{
|
||||
succeed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //普通类型的参数
|
||||
{
|
||||
if (paras[i].ParameterType != argTypes[i])
|
||||
{
|
||||
succeed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (succeed)
|
||||
{
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SearchMethod 包括被继承的所有方法,也包括泛型方法。
|
||||
/// </summary>
|
||||
public static MethodInfo SearchMethod(Type originType, string methodName, Type[] argTypes)
|
||||
{
|
||||
MethodInfo meth = originType.GetMethod(methodName, argTypes);
|
||||
if (meth != null)
|
||||
{
|
||||
return meth;
|
||||
}
|
||||
|
||||
meth = ReflectionHelper.SearchGenericMethodInType(originType, methodName, argTypes);
|
||||
if (meth != null)
|
||||
{
|
||||
return meth;
|
||||
}
|
||||
|
||||
//搜索基类
|
||||
Type baseType = originType.BaseType;
|
||||
if (baseType != null)
|
||||
{
|
||||
while (baseType != typeof(object))
|
||||
{
|
||||
MethodInfo target = baseType.GetMethod(methodName, argTypes);
|
||||
if (target != null)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
|
||||
target = ReflectionHelper.SearchGenericMethodInType(baseType, methodName, argTypes);
|
||||
if (target != null)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
|
||||
baseType = baseType.BaseType;
|
||||
}
|
||||
}
|
||||
|
||||
//搜索基接口
|
||||
if (originType.GetInterfaces() != null)
|
||||
{
|
||||
IList<MethodInfo> list = ReflectionHelper.GetAllMethods(originType.GetInterfaces());
|
||||
foreach (MethodInfo theMethod in list)
|
||||
{
|
||||
if (theMethod.Name != methodName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ParameterInfo[] args = theMethod.GetParameters();
|
||||
if (args.Length != argTypes.Length)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool correctArgType = true;
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
if (args[i].ParameterType != argTypes[i])
|
||||
{
|
||||
correctArgType = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (correctArgType)
|
||||
{
|
||||
return theMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetFullMethodName
|
||||
public static string GetMethodFullName(MethodInfo method)
|
||||
{
|
||||
return string.Format("{0}.{1}()", method.DeclaringType, method.Name);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user