ReflectionHelper.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. using Abp.Logging;
  2. using System.Reflection;
  3. namespace VberZero.Tools;
  4. public static class ReflectionHelper
  5. {
  6. public static TOut? GetFiledValue<TOut>(this object obj, string filedName)
  7. {
  8. try
  9. {
  10. var value = obj.GetType().GetProperty(filedName)?.GetValue(obj, null);
  11. return (TOut)value!;
  12. }
  13. catch (Exception e)
  14. {
  15. LogHelper.LogException(e);
  16. return default(TOut);
  17. }
  18. }
  19. public static TOut SetFiledValue<TOut, TFiled>(this TOut obj, string filedName, TFiled value)
  20. {
  21. try
  22. {
  23. var filed = obj?.GetType().GetProperty(filedName);
  24. if (filed != null)
  25. {
  26. filed.SetValue(obj, value);
  27. }
  28. }
  29. catch (Exception e)
  30. {
  31. LogHelper.LogException(e);
  32. }
  33. return obj;
  34. }
  35. public static TAttribute? GetSingleAttribute<TAttribute>(this Type type, TAttribute? defaultValue = default(TAttribute), bool inherit = true)
  36. where TAttribute : Attribute
  37. {
  38. return type.GetCustomAttributes(inherit).OfType<TAttribute>().FirstOrDefault()
  39. ?? type.ReflectedType?.GetTypeInfo().GetCustomAttributes(inherit).OfType<TAttribute>().FirstOrDefault()
  40. ?? defaultValue;
  41. }
  42. public static TAttribute? GetMemberSingleAttribute<TAttribute>(this MemberInfo memberInfo, TAttribute? defaultValue = default(TAttribute), bool inherit = true)
  43. where TAttribute : Attribute
  44. {
  45. //Get attribute on the member
  46. if (memberInfo.IsDefined(typeof(TAttribute), inherit))
  47. {
  48. return memberInfo.GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>().First();
  49. }
  50. return defaultValue;
  51. }
  52. public static Type? TypenFromAssembly(this Assembly assembly, string typeName)
  53. {
  54. Type?[] typeArray = assembly.GetTypes();
  55. foreach (var type in typeArray)
  56. {
  57. if (type != null && ((type.FullName != null && type.FullName.Equals(typeName)) || type.Name.Equals(typeName)))
  58. {
  59. return type;
  60. }
  61. }
  62. return null;
  63. }
  64. /// <summary>
  65. /// Checks whether <paramref name="givenType"/> implements/inherits <paramref name="genericType"/>.
  66. /// </summary>
  67. /// <param name="givenType">Type to check</param>
  68. /// <param name="genericType">Generic type</param>
  69. public static bool IsAssignableToGenericType(Type givenType, Type genericType)
  70. {
  71. var givenTypeInfo = givenType.GetTypeInfo();
  72. if (givenTypeInfo.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
  73. {
  74. return true;
  75. }
  76. foreach (var interfaceType in givenType.GetInterfaces())
  77. {
  78. if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == genericType)
  79. {
  80. return true;
  81. }
  82. }
  83. if (givenTypeInfo.BaseType == null)
  84. {
  85. return false;
  86. }
  87. return IsAssignableToGenericType(givenTypeInfo.BaseType, genericType);
  88. }
  89. /// <summary>
  90. /// Gets a list of attributes defined for a class member and it's declaring type including inherited attributes.
  91. /// </summary>
  92. /// <param name="inherit">Inherit attribute from base classes</param>
  93. /// <param name="memberInfo">MemberInfo</param>
  94. public static List<object> GetAttributesOfMemberAndDeclaringType(MemberInfo memberInfo, bool inherit = true)
  95. {
  96. var attributeList = new List<object>();
  97. attributeList.AddRange(memberInfo.GetCustomAttributes(inherit));
  98. if (memberInfo.DeclaringType != null)
  99. {
  100. attributeList.AddRange(memberInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(inherit));
  101. }
  102. return attributeList;
  103. }
  104. /// <summary>
  105. /// Gets a list of attributes defined for a class member and type including inherited attributes.
  106. /// </summary>
  107. /// <param name="memberInfo">MemberInfo</param>
  108. /// <param name="type">Type</param>
  109. /// <param name="inherit">Inherit attribute from base classes</param>
  110. public static List<object> GetAttributesOfMemberAndType(MemberInfo memberInfo, Type type, bool inherit = true)
  111. {
  112. var attributeList = new List<object>();
  113. attributeList.AddRange(memberInfo.GetCustomAttributes(inherit));
  114. attributeList.AddRange(type.GetTypeInfo().GetCustomAttributes(inherit));
  115. return attributeList;
  116. }
  117. /// <summary>
  118. /// Gets a list of attributes defined for a class member and it's declaring type including inherited attributes.
  119. /// </summary>
  120. /// <typeparam name="TAttribute">Type of the attribute</typeparam>
  121. /// <param name="memberInfo">MemberInfo</param>
  122. /// <param name="inherit">Inherit attribute from base classes</param>
  123. public static List<TAttribute> GetAttributesOfMemberAndDeclaringType<TAttribute>(MemberInfo memberInfo, bool inherit = true)
  124. where TAttribute : Attribute
  125. {
  126. var attributeList = new List<TAttribute>();
  127. if (memberInfo.IsDefined(typeof(TAttribute), inherit))
  128. {
  129. attributeList.AddRange(memberInfo.GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>());
  130. }
  131. if (memberInfo.DeclaringType != null && memberInfo.DeclaringType.GetTypeInfo().IsDefined(typeof(TAttribute), inherit))
  132. {
  133. attributeList.AddRange(memberInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>());
  134. }
  135. return attributeList;
  136. }
  137. /// <summary>
  138. /// Gets a list of attributes defined for a class member and type including inherited attributes.
  139. /// </summary>
  140. /// <typeparam name="TAttribute">Type of the attribute</typeparam>
  141. /// <param name="memberInfo">MemberInfo</param>
  142. /// <param name="type">Type</param>
  143. /// <param name="inherit">Inherit attribute from base classes</param>
  144. public static List<TAttribute> GetAttributesOfMemberAndType<TAttribute>(MemberInfo memberInfo, Type type, bool inherit = true)
  145. where TAttribute : Attribute
  146. {
  147. var attributeList = new List<TAttribute>();
  148. if (memberInfo.IsDefined(typeof(TAttribute), inherit))
  149. {
  150. attributeList.AddRange(memberInfo.GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>());
  151. }
  152. if (type.GetTypeInfo().IsDefined(typeof(TAttribute), inherit))
  153. {
  154. attributeList.AddRange(type.GetTypeInfo().GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>());
  155. }
  156. return attributeList;
  157. }
  158. /// <summary>
  159. /// Tries to gets an of attribute defined for a class member and it's declaring type including inherited attributes.
  160. /// Returns default value if it's not declared at all.
  161. /// </summary>
  162. /// <typeparam name="TAttribute">Type of the attribute</typeparam>
  163. /// <param name="memberInfo">MemberInfo</param>
  164. /// <param name="defaultValue">Default value (null as default)</param>
  165. /// <param name="inherit">Inherit attribute from base classes</param>
  166. public static TAttribute? GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<TAttribute>(MemberInfo memberInfo, TAttribute? defaultValue = default(TAttribute), bool inherit = true)
  167. where TAttribute : class
  168. {
  169. return memberInfo.GetCustomAttributes(true).OfType<TAttribute>().FirstOrDefault()
  170. ?? memberInfo.ReflectedType?.GetTypeInfo().GetCustomAttributes(true).OfType<TAttribute>().FirstOrDefault()
  171. ?? defaultValue;
  172. }
  173. /// <summary>
  174. /// Tries to gets an of attribute defined for a class member and it's declaring type including inherited attributes.
  175. /// Returns default value if it's not declared at all.
  176. /// </summary>
  177. /// <typeparam name="TAttribute">Type of the attribute</typeparam>
  178. /// <param name="memberInfo">MemberInfo</param>
  179. /// <param name="defaultValue">Default value (null as default)</param>
  180. /// <param name="inherit">Inherit attribute from base classes</param>
  181. public static TAttribute? GetSingleAttributeOrDefault<TAttribute>(MemberInfo memberInfo, TAttribute? defaultValue = default(TAttribute), bool inherit = true)
  182. where TAttribute : Attribute
  183. {
  184. //Get attribute on the member
  185. if (memberInfo.IsDefined(typeof(TAttribute), inherit))
  186. {
  187. return memberInfo.GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>().First();
  188. }
  189. return defaultValue;
  190. }
  191. /// <summary>
  192. /// Gets a property by it's full path from given object
  193. /// </summary>
  194. /// <param name="obj">Object to get value from</param>
  195. /// <param name="objectType">Type of given object</param>
  196. /// <param name="propertyPath">Full path of property</param>
  197. /// <returns></returns>
  198. public static object GetPropertyByPath(object obj, Type objectType, string propertyPath)
  199. {
  200. var property = obj;
  201. var currentType = objectType;
  202. var objectPath = currentType.FullName;
  203. var absolutePropertyPath = propertyPath;
  204. if (absolutePropertyPath.StartsWith(objectPath ?? throw new InvalidOperationException()))
  205. {
  206. absolutePropertyPath = absolutePropertyPath.Replace(objectPath + ".", "");
  207. }
  208. foreach (var propertyName in absolutePropertyPath.Split('.'))
  209. {
  210. property = currentType.GetProperty(propertyName);
  211. currentType = ((PropertyInfo)property!).PropertyType;
  212. }
  213. return property;
  214. }
  215. /// <summary>
  216. /// Gets value of a property by it's full path from given object
  217. /// </summary>
  218. /// <param name="obj">Object to get value from</param>
  219. /// <param name="objectType">Type of given object</param>
  220. /// <param name="propertyPath">Full path of property</param>
  221. /// <returns></returns>
  222. public static object? GetValueByPath(object obj, Type objectType, string propertyPath)
  223. {
  224. var value = obj;
  225. var currentType = objectType;
  226. var objectPath = currentType.FullName;
  227. var absolutePropertyPath = propertyPath;
  228. if (absolutePropertyPath.StartsWith(objectPath ?? throw new InvalidOperationException()))
  229. {
  230. absolutePropertyPath = absolutePropertyPath.Replace(objectPath + ".", "");
  231. }
  232. foreach (var propertyName in absolutePropertyPath.Split('.'))
  233. {
  234. var property = currentType?.GetProperty(propertyName);
  235. value = property?.GetValue(value, null);
  236. currentType = property?.PropertyType;
  237. }
  238. return value;
  239. }
  240. /// <summary>
  241. /// Sets value of a property by it's full path on given object
  242. /// </summary>
  243. /// <param name="obj"></param>
  244. /// <param name="objectType"></param>
  245. /// <param name="propertyPath"></param>
  246. /// <param name="value"></param>
  247. public static void SetValueByPath(object? obj, Type objectType, string propertyPath, object value)
  248. {
  249. var currentType = objectType;
  250. PropertyInfo? property;
  251. var objectPath = currentType.FullName;
  252. var absolutePropertyPath = propertyPath;
  253. if (absolutePropertyPath.StartsWith(objectPath ?? throw new InvalidOperationException()))
  254. {
  255. absolutePropertyPath = absolutePropertyPath.Replace(objectPath + ".", "");
  256. }
  257. var properties = absolutePropertyPath.Split('.');
  258. if (properties.Length == 1)
  259. {
  260. property = objectType.GetProperty(properties.First());
  261. property?.SetValue(obj, value);
  262. return;
  263. }
  264. for (int i = 0; i < properties.Length - 1; i++)
  265. {
  266. property = currentType?.GetProperty(properties[i]);
  267. obj = property?.GetValue(obj, null);
  268. currentType = property?.PropertyType;
  269. }
  270. property = currentType?.GetProperty(properties.Last());
  271. property?.SetValue(obj, value);
  272. }
  273. public static bool IsPropertyGetterSetterMethod(MethodInfo method, Type type)
  274. {
  275. if (!method.IsSpecialName)
  276. {
  277. return false;
  278. }
  279. if (method.Name.Length < 5)
  280. {
  281. return false;
  282. }
  283. return type.GetProperty(method.Name.Substring(4), BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic) != null;
  284. }
  285. public static async Task<object?> InvokeAsync(MethodInfo method, object obj, params object[] parameters)
  286. {
  287. var task = (Task)method.Invoke(obj, parameters)!;
  288. await task;
  289. var resultProperty = task.GetType().GetProperty("Result");
  290. return resultProperty?.GetValue(task);
  291. }
  292. }