ReflectionHelper.cs 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. using System;
  2. using System.Reflection;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Collections.Generic;
  6. using System.Linq.Expressions;
  7. using System.Diagnostics.CodeAnalysis;
  8. using System.Threading.Tasks;
  9. namespace EasyDevCore.Common
  10. {
  11. /// <summary>
  12. /// Reflection Tools
  13. /// </summary>
  14. public static class ReflectionHelper
  15. {
  16. /// <summary>
  17. /// Creates the object.
  18. /// </summary>
  19. /// <param name="typeName">Name of the type.</param>
  20. /// <param name="args">The args.</param>
  21. /// <returns></returns>
  22. public static object CreateInstance(string typeName, params object[] args) => CreateInstance(Type.GetType(typeName, true, true), args);
  23. /// <summary>
  24. /// Creates the object.
  25. /// </summary>
  26. /// <typeparam name="T"></typeparam>
  27. /// <param name="args">The arguments.</param>
  28. /// <returns></returns>
  29. public static T CreateInstance<T>(params object[] args) => (T)CreateInstance(typeof(T), args);
  30. /// <summary>
  31. /// Creates the object.
  32. /// </summary>
  33. /// <param name="type">The type.</param>
  34. /// <param name="args">The arguments.</param>
  35. /// <returns>
  36. /// <br />
  37. /// </returns>
  38. public static object CreateInstance(this Type type, params object[] args)
  39. {
  40. if (args.Length > 0)
  41. {
  42. return Activator.CreateInstance(type, args);
  43. }
  44. else
  45. {
  46. return Activator.CreateInstance(type);
  47. }
  48. }
  49. /// <summary>
  50. /// Finds the types.
  51. /// </summary>
  52. /// <param name="searchTypes">The search types.</param>
  53. /// <param name="isClass">if set to <c>true</c> [is class].</param>
  54. /// <param name="isAbstract">if set to <c>true</c> [is abstract].</param>
  55. /// <param name="isInterface">if set to <c>true</c> [is interface].</param>
  56. /// <param name="assemblyPredicate">The assembly predicate.</param>
  57. /// <param name="typePredicate">The type predicate.</param>
  58. /// <returns></returns>
  59. public static IList<Type> FindTypes(Type[] searchTypes, bool? isClass = null, bool? isAbstract = null, bool? isInterface = null, Func<Assembly, bool> assemblyPredicate = null, Func<Type, bool> typePredicate = null)
  60. {
  61. IEnumerable<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies();
  62. if (assemblyPredicate != null) assemblies = assemblies.Where(assemblyPredicate);
  63. IEnumerable<Type> types = assemblies.SelectMany(a => a.GetTypes());
  64. bool multiType = searchTypes.Length > 1;
  65. types = types.Where(t =>
  66. {
  67. bool ok = t.IsPublic && ((!multiType && searchTypes[0].IsAssignableFrom(t)) || (multiType && searchTypes.Any(st => st.IsAssignableFrom(t))));
  68. if(isClass.HasValue && t.IsClass != isClass.Value) ok = false;
  69. if(isAbstract.HasValue && t.IsAbstract != isAbstract.Value) ok = false;
  70. if(isInterface.HasValue && t.IsInterface != isInterface.Value) ok = false;
  71. return ok;
  72. });
  73. if (typePredicate != null) types = types.Where(typePredicate);
  74. return types.ToList();
  75. }
  76. /// <summary>
  77. /// Finds the types.
  78. /// </summary>
  79. /// <typeparam name="T"></typeparam>
  80. /// <param name="isClass">if set to <c>true</c> [is class].</param>
  81. /// <param name="isAbstract">if set to <c>true</c> [is abstract].</param>
  82. /// <param name="isInterface">if set to <c>true</c> [is interface].</param>
  83. /// <param name="assemblyPredicate">The assembly predicate.</param>
  84. /// <param name="typePredicate">The type predicate.</param>
  85. /// <returns></returns>
  86. public static IList<Type> FindTypes<T>(bool? isClass = null, bool? isAbstract = null, bool? isInterface = null, Func<Assembly, bool> assemblyPredicate = null, Func<Type, bool> typePredicate = null)
  87. {
  88. Type[] types = new Type[1];
  89. types[0] = typeof(T);
  90. return FindTypes(types, isClass, isAbstract, isInterface, assemblyPredicate, typePredicate);
  91. }
  92. /// <summary>
  93. /// Gets the expression custom attribute.
  94. /// </summary>
  95. /// <typeparam name="ModelType">The type of the odel type.</typeparam>
  96. /// <typeparam name="ValueType">The type of the alue type.</typeparam>
  97. /// <typeparam name="T"></typeparam>
  98. /// <param name="expression">The expression.</param>
  99. /// <returns></returns>
  100. /// <exception cref="System.ArgumentException">
  101. /// </exception>
  102. public static T GetExpressionCustomAttribute<ModelType, ValueType, T>(this Expression<Func<ModelType, ValueType>> expression)
  103. {
  104. MemberExpression member = expression.Body as MemberExpression;
  105. if (member == null)
  106. throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", expression.ToString()));
  107. PropertyInfo propInfo = member.Member as PropertyInfo;
  108. if (propInfo == null)
  109. throw new ArgumentException(string.Format("Expression '{0}' refers to a field, not a property.", expression.ToString()));
  110. var attributes = propInfo.GetCustomAttributes(typeof(T), true);
  111. if (attributes.Length > 0)
  112. return (T)attributes[0];
  113. return default(T);
  114. }
  115. /// <summary>
  116. /// Gets the expression value.
  117. /// </summary>
  118. /// <typeparam name="ModelType">The type of the model type.</typeparam>
  119. /// <typeparam name="ValueType">The type of the value type.</typeparam>
  120. /// <param name="expression">The expression.</param>
  121. /// <param name="source">The source.</param>
  122. /// <returns>ValueType.</returns>
  123. /// <exception cref="ArgumentException">
  124. /// </exception>
  125. public static ValueType GetExpressionValue<ModelType, ValueType>(this Expression<Func<ModelType, ValueType>> expression, ModelType source)
  126. {
  127. MemberExpression member = expression.Body as MemberExpression;
  128. if (member == null)
  129. throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", expression.ToString()));
  130. PropertyInfo propInfo = member.Member as PropertyInfo;
  131. if (propInfo == null)
  132. throw new ArgumentException(string.Format("Expression '{0}' refers to a field, not a property.", expression.ToString()));
  133. if (source == null) throw new ArgumentNullException(nameof(source));
  134. return (ValueType)source.GetPropertyValue(propInfo.Name);
  135. }
  136. /// <summary>
  137. /// Gets the name of the member.
  138. /// </summary>
  139. /// <typeparam name="T"></typeparam>
  140. /// <param name="memberExpression">The member expression.</param>
  141. /// <returns></returns>
  142. public static string GetMemberName<T>(Expression<Func<T>> memberExpression)
  143. {
  144. MemberExpression expressionBody = (MemberExpression)memberExpression.Body;
  145. return expressionBody.Member.Name;
  146. }
  147. /// <summary>
  148. /// Gets the PropertyInfo for the TargetProperty.
  149. /// </summary>
  150. /// <param name="target">The target object.</param>
  151. /// <param name="targetProperty">The target property.</param>
  152. /// <param name="returnType">Type of the return.</param>
  153. /// <param name="paramTypes">The param types (System.Type.EmptyTypes = no parameters).</param>
  154. /// <returns></returns>
  155. public static PropertyInfo GetPropertyInfo(this object target, string targetProperty, Type returnType = null, Type[] paramTypes = null)
  156. {
  157. if ((returnType != null) || (paramTypes != null))
  158. {
  159. return target.GetType().GetProperty(targetProperty, BindingFlags.Public | BindingFlags.Instance, null, returnType, paramTypes, null);
  160. }
  161. else
  162. {
  163. return target.GetType().GetProperty(targetProperty);
  164. }
  165. }
  166. /// <summary>
  167. /// Gets the property infos.
  168. /// </summary>
  169. /// <param name="type">The type.</param>
  170. /// <returns></returns>
  171. public static PropertyInfo[] GetPropertyInfos(this Type type)
  172. {
  173. return type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public).ToArray<PropertyInfo>();
  174. }
  175. /// <summary>
  176. /// Gets multi PropertyInfo for the TargetProperty.
  177. /// </summary>
  178. /// <param name="target">The target.</param>
  179. /// <returns></returns>
  180. public static PropertyInfo[] GetPropertyInfos(this object target)
  181. {
  182. return GetPropertyInfos(target.GetType());
  183. }
  184. /// <summary>
  185. /// Gets the method info.
  186. /// </summary>
  187. /// <param name="target">The target.</param>
  188. /// <param name="targetMethod">The target method.</param>
  189. /// <param name="paramTypes">The param types (System.Type.EmptyTypes = no parameters).</param>
  190. /// <returns></returns>
  191. public static MethodInfo GetMethodInfo(this object target, string targetMethod, Type[] paramTypes = null)
  192. {
  193. if (paramTypes != null)
  194. {
  195. return target.GetType().GetMethod(targetMethod, BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Any, paramTypes, null);
  196. }
  197. else
  198. {
  199. return target.GetType().GetMethod(targetMethod);
  200. }
  201. }
  202. /// <summary>
  203. /// Gets the method info.
  204. /// </summary>
  205. /// <param name="target">The target.</param>
  206. /// <param name="targetMethod">The target method.</param>
  207. /// <returns></returns>
  208. public static MethodInfo[] GetMethodInfos(this object target, string targetMethod)
  209. {
  210. return target.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)
  211. .Where((mi) => mi.Name == targetMethod).ToArray<MethodInfo>();
  212. }
  213. /// <summary>
  214. /// Invokes the method.
  215. /// </summary>
  216. /// <param name="target">The target.</param>
  217. /// <param name="targetMethod">The target method.</param>
  218. /// <param name="args">The args.</param>
  219. /// <returns></returns>
  220. public static object InvokeMethod<T>(this T target, string targetMethod, params object[] args) where T: class
  221. {
  222. MethodInfo methodInfo = GetMethodInfo(target, targetMethod);
  223. if (methodInfo == null)
  224. return null;
  225. return methodInfo.Invoke(target, args);
  226. }
  227. /// <summary>
  228. /// Invokes the method asynchronous.
  229. /// </summary>
  230. /// <typeparam name="T"></typeparam>
  231. /// <typeparam name="R"></typeparam>
  232. /// <param name="target">The target.</param>
  233. /// <param name="targetMethod">The target method.</param>
  234. /// <param name="args">The arguments.</param>
  235. /// <returns></returns>
  236. public static async Task<R> InvokeMethodAsync<T, R>(this T target, string targetMethod, params object[] args) where T : class
  237. {
  238. dynamic awaitable = (R)target.InvokeMethod(targetMethod, args);
  239. await awaitable;
  240. return awaitable.GetAwaiter().GetResult();
  241. }
  242. /// <summary>
  243. /// Checks the attribute exists.
  244. /// </summary>
  245. /// <typeparam name="T"></typeparam>
  246. /// <param name="target">The target.</param>
  247. /// <returns></returns>
  248. public static bool CheckAttributeExists<T>(this object target)
  249. where T : Attribute
  250. {
  251. return Attribute.IsDefined(target.GetType().Assembly, typeof(T));
  252. }
  253. /// <summary>
  254. /// Gets the attribute.
  255. /// </summary>
  256. /// <typeparam name="T"></typeparam>
  257. /// <param name="target">The target.</param>
  258. /// <returns></returns>
  259. public static T GetAttribute<T>(this object target)
  260. where T : Attribute
  261. {
  262. return (T)Attribute.GetCustomAttribute(target.GetType().Assembly, typeof(T));
  263. }
  264. /// <summary>
  265. /// Gets the attributes.
  266. /// </summary>
  267. /// <typeparam name="T"></typeparam>
  268. /// <param name="target">The target.</param>
  269. /// <returns></returns>
  270. public static T[] GetAttributes<T>(this object target)
  271. where T : Attribute
  272. {
  273. return (T[])Attribute.GetCustomAttributes(target.GetType().Assembly, typeof(T));
  274. }
  275. /// <summary>
  276. /// Checks the property exists.
  277. /// </summary>
  278. /// <param name="target">The target.</param>
  279. /// <param name="targetProperty">The target property.</param>
  280. /// <returns></returns>
  281. public static bool CheckPropertyExist(this object target, string targetProperty)
  282. {
  283. if (target is System.Dynamic.ExpandoObject)
  284. {
  285. return ((IDictionary<String, object>)target).ContainsKey(targetProperty);
  286. }
  287. else
  288. {
  289. object obj = target;
  290. PropertyDescriptor prop;
  291. while (true)
  292. {
  293. if (targetProperty.Contains("."))
  294. {
  295. string parentProperty = targetProperty.Substring(0, targetProperty.IndexOf("."));
  296. prop = TypeDescriptor.GetProperties(obj)[parentProperty];
  297. obj = prop.GetValue(obj);
  298. targetProperty = targetProperty.Substring(parentProperty.Length + 1);
  299. }
  300. else
  301. {
  302. prop = TypeDescriptor.GetProperties(obj)[targetProperty];
  303. break;
  304. }
  305. }
  306. return (prop != null);
  307. }
  308. }
  309. /// <summary>
  310. /// Gets the property values.
  311. /// </summary>
  312. /// <param name="target">The target.</param>
  313. /// <returns></returns>
  314. public static IDictionary<string, object> GetPropertyValues(this object target)
  315. {
  316. Dictionary<string, object> valuePairs = new Dictionary<string, object>();
  317. foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(target))
  318. {
  319. valuePairs.Add(prop.Name, prop.GetValue(target));
  320. }
  321. return valuePairs;
  322. }
  323. /// <summary>
  324. /// Gets the property value for the TargetProperty.
  325. /// </summary>
  326. /// <param name="target">The target object.</param>
  327. /// <param name="targetProperty">The target property.</param>
  328. /// <returns>The property value.</returns>
  329. public static object GetPropertyValue(this object target, string targetProperty)
  330. {
  331. if (target is System.Dynamic.ExpandoObject)
  332. {
  333. if (CheckPropertyExist(target, targetProperty))
  334. {
  335. return ((IDictionary<String, object>)target)[targetProperty];
  336. }
  337. return null;
  338. }
  339. else
  340. {
  341. object obj = target;
  342. PropertyDescriptor prop;
  343. while (true)
  344. {
  345. if (targetProperty.Contains("."))
  346. {
  347. string parentProperty = targetProperty.Substring(0, targetProperty.IndexOf("."));
  348. prop = TypeDescriptor.GetProperties(obj)[parentProperty];
  349. obj = prop.GetValue(obj);
  350. targetProperty = targetProperty.Substring(parentProperty.Length + 1);
  351. }
  352. else
  353. {
  354. prop = TypeDescriptor.GetProperties(obj)[targetProperty];
  355. break;
  356. }
  357. }
  358. return (prop == null) ? null : prop.GetValue(obj);
  359. }
  360. }
  361. /// <summary>
  362. /// Gets the indexer value.
  363. /// </summary>
  364. /// <param name="target">The target.</param>
  365. /// <param name="indexValue">The index value.</param>
  366. /// <param name="targetParentProperty">The target parent property.</param>
  367. /// <returns></returns>
  368. public static object GetIndexerValue(this object target, object indexValue, string targetParentProperty = "")
  369. {
  370. object obj = target;
  371. PropertyDescriptor prop;
  372. PropertyInfo pi;
  373. while (true)
  374. {
  375. if (targetParentProperty.Contains("."))
  376. {
  377. string parentProperty = targetParentProperty.Substring(0, targetParentProperty.IndexOf("."));
  378. prop = TypeDescriptor.GetProperties(obj)[parentProperty];
  379. obj = prop.GetValue(obj);
  380. targetParentProperty = targetParentProperty.Substring(parentProperty.Length + 1);
  381. }
  382. else
  383. {
  384. pi = GetPropertyInfo(obj, "Item", null, new Type[] { indexValue.GetType() });
  385. break;
  386. }
  387. }
  388. return (pi == null) ? null : pi.GetValue(obj, new object[] { indexValue });
  389. }
  390. /// <summary>
  391. /// Gets the indexer value.
  392. /// </summary>
  393. /// <typeparam name="T"></typeparam>
  394. /// <param name="target">The target.</param>
  395. /// <param name="indexValue">The index value.</param>
  396. /// <param name="targetParentProperty">The target parent property.</param>
  397. /// <returns></returns>
  398. public static T GetIndexerValue<T>(this object target, object indexValue, string targetParentProperty = "")
  399. {
  400. return (T)GetIndexerValue(target, indexValue, targetParentProperty);
  401. }
  402. /// <summary>
  403. /// Sets the indexer value.
  404. /// </summary>
  405. /// <param name="target">The target.</param>
  406. /// <param name="indexValue">The index value.</param>
  407. /// <param name="value">The value.</param>
  408. /// <param name="targetParentProperty">The target parent property.</param>
  409. public static void SetIndexerValue<T>(this T target, object indexValue, object value, string targetParentProperty = "") where T: class
  410. {
  411. object obj = target;
  412. PropertyDescriptor prop;
  413. PropertyInfo pi;
  414. while (true)
  415. {
  416. if (targetParentProperty.Contains("."))
  417. {
  418. string parentProperty = targetParentProperty.Substring(0, targetParentProperty.IndexOf("."));
  419. prop = TypeDescriptor.GetProperties(obj)[parentProperty];
  420. obj = prop.GetValue(obj);
  421. targetParentProperty = targetParentProperty.Substring(parentProperty.Length + 1);
  422. }
  423. else
  424. {
  425. pi = GetPropertyInfo(obj, "Item", null, new Type[] { indexValue.GetType() });
  426. break;
  427. }
  428. }
  429. pi.SetValue(obj, value, new object[] { indexValue });
  430. }
  431. /// <summary>
  432. /// Gets the property value for the TargetProperty.
  433. /// </summary>
  434. /// <typeparam name="T">The type of the property.</typeparam>
  435. /// <param name="target">The target object.</param>
  436. /// <param name="targetProperty">The target property.</param>
  437. /// <returns>The property value.</returns>
  438. public static T GetPropertyValue<T>(this object target, string targetProperty)
  439. {
  440. return (T)(GetPropertyValue(target, targetProperty) ?? default(T));
  441. }
  442. /// <summary>
  443. /// Gets the property value for the TargetProperty and convert to T, if not success uses default value.
  444. /// </summary>
  445. /// <typeparam name="T">The type of the property.</typeparam>
  446. /// <param name="target">The target object.</param>
  447. /// <param name="targetProperty">The target property.</param>
  448. /// <param name="defaultValue">The default value.</param>
  449. /// <returns>
  450. /// The property value.
  451. /// </returns>
  452. public static T GetPropertyValue<T>(this object target, string targetProperty, T defaultValue)
  453. {
  454. if (CheckPropertyExist(target, targetProperty))
  455. {
  456. var value = GetPropertyValue(target, targetProperty);
  457. return value == null ? defaultValue : value.ConvertTo<T>(defaultValue);
  458. }
  459. else
  460. {
  461. return defaultValue;
  462. }
  463. }
  464. /// <summary>
  465. /// Sets the property value for the TargetProperty.
  466. /// </summary>
  467. /// <param name="target">The target object.</param>
  468. /// <param name="targetProperty">The target property.</param>
  469. /// <param name="value">The value to set.</param>
  470. public static void SetPropertyValue<T>(this T target, string targetProperty, object value)
  471. {
  472. if (target == null)
  473. throw new ArgumentNullException("target", "Target object can not be Null.");
  474. if (target is System.Dynamic.ExpandoObject)
  475. {
  476. ((IDictionary<String, object>)target)[targetProperty] = value;
  477. }
  478. else
  479. {
  480. object obj = target;
  481. PropertyDescriptor prop;
  482. while (true)
  483. {
  484. if (targetProperty.Contains("."))
  485. {
  486. string parentProperty = targetProperty.Substring(0, targetProperty.IndexOf("."));
  487. prop = TypeDescriptor.GetProperties(obj)[parentProperty];
  488. obj = prop.GetValue(obj);
  489. targetProperty = targetProperty.Substring(parentProperty.Length + 1);
  490. }
  491. else
  492. {
  493. prop = TypeDescriptor.GetProperties(obj)[targetProperty];
  494. break;
  495. }
  496. }
  497. if (value == null)
  498. prop.SetValue(obj, null);
  499. else
  500. {
  501. SetPropertyValue(target, prop, value);
  502. }
  503. }
  504. }
  505. /// <summary>
  506. /// Sets the property value.
  507. /// </summary>
  508. /// <typeparam name="TModel">The type of the model.</typeparam>
  509. /// <param name="model">The model.</param>
  510. /// <param name="prop">The property.</param>
  511. /// <param name="value">The value.</param>
  512. public static void SetPropertyValue<TModel>(TModel model, PropertyDescriptor prop, object value)
  513. {
  514. if (value == null)
  515. {
  516. prop.SetValue(model, null);
  517. return;
  518. }
  519. Type pType = prop.PropertyType.GetUnderlyingType();
  520. Type vType = value.GetType().GetUnderlyingType();
  521. if (pType != null && (pType.Equals(vType) || pType.FullName == "System.Object"))
  522. {
  523. // types match, just copy value
  524. prop.SetValue(model, value);
  525. }
  526. else
  527. {
  528. // types don't match, try to coerce
  529. if (pType.Equals(typeof(Guid)))
  530. {
  531. prop.SetValue(model, new Guid(value.ToString()));
  532. }
  533. else if (pType.IsEnum && vType.Equals(typeof(string)))
  534. prop.SetValue(model, Enum.Parse(pType, value.ToString()));
  535. else if (pType.IsEnum && vType.IsNumericType())
  536. prop.SetValue(model, value.ConvertTo<int>());
  537. else
  538. prop.SetValue(model, Convert.ChangeType(value, pType));
  539. }
  540. }
  541. /// <summary>
  542. /// Invokes the generic method.
  543. /// </summary>
  544. /// <param name="type">The type.</param>
  545. /// <param name="interfaceType">Type of the interface.</param>
  546. /// <param name="methodName">Name of the method.</param>
  547. /// <param name="args">The arguments.</param>
  548. /// <returns></returns>
  549. public static object InvokeGenericStaticMethod(this Type type, Type interfaceType, string methodName, params object[] args)
  550. {
  551. MethodInfo mi = type.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).First(f => f.Name == methodName);
  552. MethodInfo miConstructed = mi.MakeGenericMethod(interfaceType);
  553. return miConstructed.Invoke(null, args != null && args.Length > 0 ? args : null);
  554. }
  555. /// <summary>
  556. /// Invokes the generic static method asynchronous.
  557. /// </summary>
  558. /// <param name="type">The type.</param>
  559. /// <param name="interfaceType">Type of the interface.</param>
  560. /// <param name="methodName">Name of the method.</param>
  561. /// <param name="args">The arguments.</param>
  562. /// <returns></returns>
  563. public static async Task<T> InvokeGenericStaticMethodAsync<T>(this Type type, Type interfaceType, string methodName, params object[] args)
  564. {
  565. MethodInfo mi = type.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).First(f => f.Name == methodName);
  566. MethodInfo miConstructed = mi.MakeGenericMethod(interfaceType);
  567. Task<T> result = (Task<T>)miConstructed.Invoke(null, args != null && args.Length > 0 ? args : null);
  568. return await result;
  569. }
  570. /// <summary>
  571. /// Invokes the generic method.
  572. /// </summary>
  573. /// <param name="obj">The object.</param>
  574. /// <param name="interfaceType">Type of the interface.</param>
  575. /// <param name="methodName">Name of the method.</param>
  576. /// <param name="args">The arguments.</param>
  577. /// <returns></returns>
  578. public static object InvokeGenericMethod(this object obj, Type interfaceType, string methodName, params object[] args)
  579. {
  580. MethodInfo mi = obj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).First(f => f.Name == methodName);
  581. MethodInfo miConstructed = mi.MakeGenericMethod(interfaceType);
  582. return miConstructed.Invoke(obj, args != null && args.Length > 0 ? args : null);
  583. }
  584. /// <summary>
  585. /// Invokes the generic method asynchronous.
  586. /// </summary>
  587. /// <param name="obj">The object.</param>
  588. /// <param name="interfaceType">Type of the interface.</param>
  589. /// <param name="methodName">Name of the method.</param>
  590. /// <param name="args">The arguments.</param>
  591. /// <returns></returns>
  592. public static async Task<object> InvokeGenericMethodAsync(this object obj, Type interfaceType, string methodName, params object[] args)
  593. {
  594. MethodInfo mi = obj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).First(f => f.Name == methodName);
  595. MethodInfo miConstructed = mi.MakeGenericMethod(interfaceType);
  596. Task<object> result = (Task<object>)miConstructed.Invoke(obj, args != null && args.Length > 0 ? args : null);
  597. return await result;
  598. }
  599. }
  600. }