using NetWorkHelper.IBase; using System; using System.Collections.Generic; using System.IO; using System.Reflection; namespace NetWorkHelper.Helper { public static class ReflectionHelper { #region 获取类型 /// /// GetType 通过完全限定的类型名来加载对应的类型。typeAndAssName如"NetWorkHelper.Filters.SourceFilter,NetWorkHelper"。 /// 如果为系统简单类型,则可以不带程序集名称。 /// 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()); } /// /// GetType 加载assemblyName程序集中的名为typeFullName的类型。assemblyName不用带扩展名,如果目标类型在当前程序集中,assemblyName传入null /// 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 /// /// LoadDerivedInstance 将程序集中所有继承自TBase的类型实例化 /// /// 基础类型(或接口类型) /// 目标程序集 /// TBase实例列表 public static IList LoadDerivedInstance(Assembly asm) { IList list = new List(); 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 /// /// LoadDerivedType 加载directorySearched目录下所有程序集中的所有派生自baseType的类型 /// /// 基类(或接口)类型 /// 搜索的目录 /// 是否搜索子目录中的程序集 /// 高级配置,可以传入null采用默认配置 /// 所有从BaseType派生的类型列表 public static IList LoadDerivedType(Type baseType, string directorySearched, bool searchChildFolder, TypeLoadConfig config) { if (config == null) { config = new TypeLoadConfig(); } IList derivedTypeList = new List(); 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; /// /// CopyToMem 是否将程序集拷贝到内存后加载 /// public bool CopyToMemory { get { return copyToMemory; } set { copyToMemory = value; } } #endregion #region LoadAbstractType private bool loadAbstractType = false; /// /// LoadAbstractType 是否加载抽象类型 /// public bool LoadAbstractType { get { return loadAbstractType; } set { loadAbstractType = value; } } #endregion #region TargetFilePostfix private string targetFilePostfix = ".dll"; /// /// TargetFilePostfix 搜索的目标程序集的后缀名 /// public string TargetFilePostfix { get { return targetFilePostfix; } set { targetFilePostfix = value; } } #endregion } #endregion #region LoadDerivedTypeInAllFolder private static void LoadDerivedTypeInAllFolder(Type baseType, IList 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 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 /// /// SetProperty 如果list中的object具有指定的propertyName属性,则设置该属性的值为proValue /// public static void SetProperty(IList 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); } /// /// SetProperty 如果object具有指定的propertyName属性,则设置该属性的值为proValue /// 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 /// /// GetProperty 根据指定的属性名获取目标对象该属性的值 /// 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 /// /// GetFieldValue 取得目标对象的指定field的值,field可以是private /// 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 /// /// SetFieldValue 设置目标对象的指定field的值,field可以是private /// 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 /// /// CopyProperty 将source中的属性的值赋给target上同名的属性 /// 使用CopyProperty可以方便的实现拷贝构造函数 /// public static void CopyProperty(object source, object target) { ReflectionHelper.CopyProperty(source, target, null); } /// /// CopyProperty 将source中的属性的值赋给target上想匹配的属性,匹配关系通过propertyMapItemList确定 /// public static void CopyProperty(object source, object target, IList 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 /// /// GetAllMethods 获取接口的所有方法信息,包括继承的 /// public static IList GetAllMethods(params Type[] interfaceTypes) { foreach (Type interfaceType in interfaceTypes) { if (!interfaceType.IsInterface) { throw new Exception("Target Type must be interface!"); } } IList list = new List(); foreach (Type interfaceType in interfaceTypes) { ReflectionHelper.DistillMethods(interfaceType, ref list); } return list; } private static void DistillMethods(Type interfaceType, ref IList 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); } } /// /// SearchGenericMethodInType 搜索指定类型定义的泛型方法,不包括继承的。 /// 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 { 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; } /// /// SearchMethod 包括被继承的所有方法,也包括泛型方法。 /// 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 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 } }