using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; public static class CultCacheExtensions { private static Dictionary InterfaceClasses = new Dictionary(); public static Type[] GetAllInterfaceClasses(this Type type) { if (InterfaceClasses.ContainsKey(type)) return InterfaceClasses[type]; return InterfaceClasses[type] = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(ass => ass.GetTypes()).Where(t => t.IsClass && t.GetInterfaces().Contains(type)).ToArray(); } private static Dictionary ParentTypes = new Dictionary(); public static Type[] GetParentTypes(this Type type) { if (ParentTypes.ContainsKey(type)) return ParentTypes[type]; return ParentTypes[type] = type.GetParents().ToArray(); } private static IEnumerable GetParents(this Type type) { // is there any base type? if (type == null) { yield break; } yield return type; // return all implemented or inherited interfaces foreach (var i in type.GetInterfaces()) { yield return i; } // return all inherited types var currentBaseType = type.BaseType; while (currentBaseType != null) { yield return currentBaseType; currentBaseType= currentBaseType.BaseType; } } private static Dictionary ChildClasses = new Dictionary(); public static Type[] GetAllChildClasses(this Type type) { if (ChildClasses.ContainsKey(type)) return ChildClasses[type]; return ChildClasses[type] = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(ass => ass.GetTypes()).Where(type.IsAssignableFrom).ToArray(); } private static Dictionary GenericChildClasses = new Dictionary(); public static Type[] GetAllGenericChildClasses(this Type genericType) { if (GenericChildClasses.ContainsKey(genericType)) return ChildClasses[genericType]; return ChildClasses[genericType] = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(ass => ass.GetTypes()).Where(type=>type.IsAssignableToGenericType(genericType)).ToArray(); } public static bool IsAssignableToGenericType(this Type givenType, Type genericType) { var interfaceTypes = givenType.GetInterfaces(); foreach (var it in interfaceTypes) { if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType) return true; } if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType) return true; Type baseType = givenType.BaseType; if (baseType == null) return false; return IsAssignableToGenericType(baseType, genericType); } public static async void WrapAwait(this Task task) { await task; } }