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