public static IEnumerable <Type> SearchForPossibleTypes(Type baseType, bool mustFind) { IEnumerable <Type> result; if (baseType == null || baseType == typeof(Entity)) { result = GetDomainEntityTypes(); } else if (baseType.IsInterface) { result = Entity.Database.AssemblyProviderFactories.Except(f => f.Value.SupportsPolymorphism()) .Select(a => a.Key).Where(a => a.References(baseType.Assembly)).Concat(baseType.Assembly) .SelectMany(a => a.GetExportedTypes()) .Where(t => t.Implements(baseType)).ToList(); } else { result = baseType.Assembly.GetExportedTypes().Where(t => t.GetParentTypes().Contains(baseType)).Union(new[] { baseType }); } result = result // Not transient objects: .Where(t => !TransientEntityAttribute.IsTransient(t)) // No abstract or interface: .Where(t => !t.IsAbstract && !t.IsInterface) // Unless the type is marked non-persistent: .Where(t => PersistentAttribute.IsTypePersistent(t)) // Leaf nodes first (most concrete): .OrderByDescending(t => t.GetParentTypes().Count()); result = result.Except(new[] { typeof(IApplicationEvent) }).ToArray(); if (result.None()) { if (baseType != null && mustFind) { throw new ArgumentException($"No type in the current application domain can be the implementation of the type {baseType.FullName}."); } else if (mustFind) { throw new ArgumentException("No type in the current application domain implements Entity."); } } return(result); }
public static IEnumerable <Type> SearchForPossibleTypes(Type baseType, bool mustFind) { IEnumerable <Type> result; if (baseType == null || baseType == typeof(Entity)) { result = GetDomainEntityTypes(); } else if (baseType.IsInterface) { result = AppDomain.CurrentDomain.FindImplementers(baseType); } else { result = baseType.Assembly.GetExportedTypes().Where(t => t.GetParentTypes().Contains(baseType)).Union(new[] { baseType }); } Log.For(typeof(EntityFinder)).Info("Found :" + result.Select(c => c.FullName).ToString("|")); result = result // Not transient objects: .Where(t => !TransientEntityAttribute.IsTransient(t)) // No abstract or interface: .Where(t => !t.IsAbstract && !t.IsInterface) // Unless the type is marked non-persistent: .Where(t => PersistentAttribute.IsTypePersistent(t)) // Leaf nodes first (most concrete): .OrderByDescending(t => t.GetParentTypes().Count()); Log.For(typeof(EntityFinder)).Info("Desirable types :" + result.Select(c => c.FullName).ToString("|")); if (result.None()) { if (baseType != null && mustFind) { throw new ArgumentException($"No type in the current application domain can be the implementation of the type {baseType.FullName}."); } else if (mustFind) { throw new ArgumentException("No type in the current application domain implements Entity."); } } return(result); }