ReflectionHelper.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Text;
  7. using WCS.Core.BaseExtensions;
  8. namespace WCS.Core.Helpers
  9. {
  10. /// <summary>
  11. /// 反射辅助类
  12. /// </summary>
  13. public class ReflectionHelper
  14. {
  15. /// <summary>
  16. /// 创建指定类型的实例
  17. /// </summary>
  18. /// <typeparam name="TModel"></typeparam>
  19. /// <param name="type"></param>
  20. /// <returns></returns>
  21. public static TModel CreateInstance<TModel>(Type type) => (TModel)ReflectionHelper.CreateInstance(type);
  22. /// <summary>
  23. /// 创建指定类型的实例
  24. /// </summary>
  25. /// <param name="type"></param>
  26. /// <returns></returns>
  27. public static object CreateInstance(Type type) => Activator.CreateInstance(type);
  28. /// <summary>
  29. /// 从当前程序中 获取所有实现指定接口的类型
  30. /// </summary>
  31. /// <typeparam name="TInterface"></typeparam>
  32. /// <returns></returns>
  33. public static List<Type> GetTypesByImplementInterface<TInterface>() where TInterface : class => GetAssemblies().SelectMany(GetTypesByImplementInterface<TInterface>).ToList();
  34. /// <summary>
  35. /// 从指定的程序集里 获取所有实现指定接口的类型
  36. /// </summary>
  37. /// <typeparam name="TInterface"></typeparam>
  38. /// <param name="assembly"></param>
  39. /// <returns></returns>
  40. public static List<Type> GetTypesByImplementInterface<TInterface>(Assembly assembly) where TInterface : class
  41. {
  42. try
  43. {
  44. return assembly.GetTypes() //获取该程序集中所有的类
  45. .Where(type => !string.IsNullOrWhiteSpace(type.Namespace))//命名空间不为空
  46. .Where(type => type.GetTypeInfo().IsClass) //必须要有类
  47. .Where(type => type.GetTypeInfo().BaseType != null)//基本类型不为空
  48. .Where(type => !type.GetTypeInfo().IsAbstract) //没有作废弃用
  49. // IsAssignableFrom
  50. // 方法的作用
  51. // a对象所对应类信息是b对象所对应的类信息的父类或者是父接口,简单理解即a是b的父类或接口 a对象所对应类信息与b对象所对应的类信息相同,简单理解即a和b为同一个类或同一个接口
  52. .Where(type => typeof(TInterface).IsAssignableFrom(type))// 当前类是否继承或指定接口
  53. .ToList();
  54. }
  55. catch
  56. {
  57. return new List<Type>();
  58. }
  59. }
  60. /// <summary>
  61. /// 从指定的程序集里 获取所有实现指定接口的类型
  62. /// </summary>
  63. /// <typeparam name="TInterface"></typeparam>
  64. /// <param name="assemblies"></param>
  65. /// <returns></returns>
  66. public static List<Type> GetTypesByImplementInterface<TInterface>(List<Assembly> assemblies) where TInterface : class
  67. {
  68. try
  69. {
  70. List<Type> types = new List<Type>();
  71. assemblies.ForEach(p =>
  72. {
  73. types.AddRange(p.GetTypes() //获取该程序集中所有的类
  74. .Where(type => !string.IsNullOrWhiteSpace(type.Namespace))//命名空间不为空
  75. .Where(type => type.GetTypeInfo().IsClass) //必须要有类
  76. .Where(type => type.GetTypeInfo().BaseType != null)//基本类型不为空
  77. .Where(type => !type.GetTypeInfo().IsAbstract) //没有作废弃用
  78. // IsAssignableFrom
  79. // 方法的作用
  80. // a对象所对应类信息是b对象所对应的类信息的父类或者是父接口,简单理解即a是b的父类或接口 a对象所对应类信息与b对象所对应的类信息相同,简单理解即a和b为同一个类或同一个接口
  81. .Where(type => typeof(TInterface).IsAssignableFrom(type))// 当前类是否继承或指定接口
  82. .ToList());
  83. });
  84. return types;
  85. }
  86. catch
  87. {
  88. return new List<Type>();
  89. }
  90. }
  91. /// <summary>
  92. /// 获取项目中所有程序集 (注意,排除了一些指定的程序集)
  93. /// </summary>
  94. /// <remarks>AppContext.BaseDirectory 方法的作用是获取程序所在目录</remarks>
  95. /// <returns></returns>
  96. public static List<Assembly> GetAssemblies()
  97. {
  98. var assemblies = new List<Assembly>();
  99. foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
  100. {
  101. assembly.GetReferencedAssemblies().RemoveTheAssemblyNamespecified().ToList()
  102. .ForEach(p =>
  103. {
  104. try
  105. {
  106. assemblies.Add(Assembly.Load(p));
  107. }
  108. catch (Exception ex)
  109. {
  110. Log(" 警告! 加载程序集失败:" + p.FullName);
  111. Log(" 错误: " + ex.Message);
  112. }
  113. });
  114. }
  115. assemblies.AddRange(GetAssemblies(AppContext.BaseDirectory));
  116. return assemblies.RemoveDuplicateAssemblies().ToList();
  117. }
  118. /// <summary>
  119. /// 从指定的目录开始,提取所有可用的程序集,向上查找引用的
  120. /// </summary>
  121. /// <param name="path"></param>
  122. /// <returns></returns>
  123. public static List<Assembly> GetAssemblies(string path)
  124. {
  125. var source = new List<Assembly>(); //需要返回的数据集合
  126. foreach (var file in Directory.GetFiles(path, "*.dll"))//读取指定目录中所有的DLL文件路径,并遍历
  127. {
  128. //try
  129. //{
  130. var a = Assembly.GetEntryAssembly();
  131. var assembly = Assembly.LoadFrom(file); //将获取到的程序集加载出来
  132. source.Add(assembly); //将该程序集加入到需要返回的数据中
  133. //找到所有引用过这个程序集的程序集的名称,并进行遍历
  134. assembly.GetReferencedAssemblies().RemoveTheAssemblyNamespecified().ToList()
  135. .ForEach(p =>
  136. {
  137. try
  138. {
  139. source.Add(Assembly.Load(p));
  140. }
  141. catch (Exception ex)
  142. {
  143. Log(" 警告! 加载程序集失败:" + p.FullName);
  144. Log(" 错误: " + ex.Message);
  145. }
  146. });
  147. //}
  148. //catch (Exception ex)
  149. //{
  150. // Log(" 警告! 提取程序集失败:" + file);
  151. // Log(" 错误: " + ex.Message);
  152. //}
  153. }
  154. return source.DistinctBy(p => p.FullName).ToList();
  155. }
  156. /// <summary>
  157. /// 写日志
  158. /// </summary>
  159. /// <param name="_">日志内容</param>
  160. private static void Log(string _)
  161. {
  162. }
  163. }
  164. }