/// <summary> /// Computes the closure of known types for all the known entities. /// See <see cref="EntityKnownTypes"/> /// </summary> /// <returns>A dictionary, keyed by entity type and containing all the /// declared known types for it, including the transitive closure. /// </returns> private Dictionary <Type, HashSet <Type> > ComputeEntityKnownTypes() { Dictionary <Type, HashSet <Type> > closure = new Dictionary <Type, HashSet <Type> >(); // Gather all the explicit known types from attributes. // Because we ask to inherit [KnownType], we will collect the full closure foreach (Type entityType in this.EntityTypes) { // Get all [KnownType]'s and subselect only those that actually derive from this entity IEnumerable <Type> knownTypes = KnownTypeUtilities.ImportKnownTypes(entityType, /* inherit */ true).Where(t => entityType.IsAssignableFrom(t)); closure[entityType] = new HashSet <Type>(knownTypes); } // 2nd pass -- add all the derived types' known types back to their base so we have the closure foreach (Type entityType in this.EntityTypes) { IEnumerable <Type> knownTypes = closure[entityType]; for (Type baseType = this.GetEntityBaseType(entityType); baseType != null; baseType = this.GetEntityBaseType(baseType)) { HashSet <Type> hash = closure[baseType]; foreach (Type knownType in knownTypes) { hash.Add(knownType); } } } return(closure); }
/// <summary> /// Recursively add the specified entity and all entities in its Include graph /// to our list of all entities, and register an associated metadata type descriptor /// for each. /// </summary> /// <param name="entityType">type of entity to add</param> public void AddEntityType(Type entityType) { if (IsKnownEntityType(entityType)) { // we've already visited this type return; } // Ensure this type can really be used as an entity type string errorMessage; if (!IsValidEntityType(entityType, out errorMessage)) { Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, Resource.Invalid_Entity_Type, entityType.Name, errorMessage)); return; } _entityTypes.Add(entityType); // Any new entity invalidates our cached entity hierarchies _entityKnownTypes = null; RegisterCustomTypeDescriptors(entityType); // Recursively add any derived entity types specified by [KnownType] // attributes var knownTypes = KnownTypeUtilities.ImportKnownTypes(entityType, true); foreach (var t in knownTypes) { if (entityType.IsAssignableFrom(t)) { AddEntityType(t); } } }