TypeFinder.cs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using VCommon.Collections;
  6. using VCommon.Logging;
  7. namespace VCommon.Reflection
  8. {
  9. public static class TypeFinder
  10. {
  11. public static ILogger Logger { get; set; } = DefaultLogger.Instance;
  12. private static readonly LazyHolder<IReadOnlyCollection<Type>> Holder = new LazyHolder<IReadOnlyCollection<Type>>(CreateTypeList);
  13. public static IReadOnlyCollection<Type> AllTypes => Holder.Instance;
  14. public static Type[] Find(Func<Type, bool> predicate) => AllTypes.Where(predicate).ToArray();
  15. private static List<Type> CreateTypeList()
  16. {
  17. var allTypes = new List<Type>();
  18. var assemblies = AppDomain.CurrentDomain.GetAssemblies().Distinct();
  19. foreach (var assembly in assemblies)
  20. {
  21. try
  22. {
  23. Type[] typesInThisAssembly;
  24. try
  25. {
  26. typesInThisAssembly = assembly.GetTypes();
  27. }
  28. catch (ReflectionTypeLoadException ex)
  29. {
  30. typesInThisAssembly = ex.Types;
  31. }
  32. if (typesInThisAssembly.IsNullOrEmpty())
  33. {
  34. continue;
  35. }
  36. allTypes.AddRange(typesInThisAssembly.Where(type => type != null));
  37. }
  38. catch (Exception ex)
  39. {
  40. Logger.Warn(ex.ToString(), ex);
  41. }
  42. }
  43. return allTypes;
  44. }
  45. }
  46. }