Exemplo n.º 1
0
        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 =
                    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);
        }