コード例 #1
0
        internal ObjectItemLoadingSessionData(KnownAssembliesSet knownAssemblies, LockedAssemblyCache lockedAssemblyCache, EdmItemCollection edmItemCollection, Action <String> logLoadMessage, object loaderCookie)
        {
            Debug.Assert(loaderCookie == null || loaderCookie is Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>, "This is a bad loader cookie");

            _typesInLoading      = new Dictionary <string, EdmType>(StringComparer.Ordinal);
            _errors              = new List <EdmItemError>();
            _knownAssemblies     = knownAssemblies;
            _lockedAssemblyCache = lockedAssemblyCache;
            _loadersThatNeedLevel1PostSessionProcessing = new HashSet <ObjectItemAssemblyLoader>();
            _loadersThatNeedLevel2PostSessionProcessing = new HashSet <ObjectItemAssemblyLoader>();
            _edmItemCollection    = edmItemCollection;
            _loadMessageLogger    = new LoadMessageLogger(logLoadMessage);
            _cspaceToOspace       = new Dictionary <EdmType, EdmType>();
            _loaderFactory        = (Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>)loaderCookie;
            _originalLoaderCookie = loaderCookie;
            if (_loaderFactory == ObjectItemConventionAssemblyLoader.Create && _edmItemCollection != null)
            {
                foreach (KnownAssemblyEntry entry in _knownAssemblies.GetEntries(_loaderFactory, edmItemCollection))
                {
                    foreach (EdmType type in entry.CacheEntry.TypesInAssembly.OfType <EdmType>())
                    {
                        if (Helper.IsEntityType(type))
                        {
                            ClrEntityType entityType = (ClrEntityType)type;
                            _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(entityType.CSpaceTypeName), entityType);
                        }
                        else if (Helper.IsComplexType(type))
                        {
                            ClrComplexType complexType = (ClrComplexType)type;
                            _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(complexType.CSpaceTypeName), complexType);
                        }
                        else if (Helper.IsEnumType(type))
                        {
                            ClrEnumType enumType = (ClrEnumType)type;
                            _cspaceToOspace.Add(_edmItemCollection.GetItem <EnumType>(enumType.CSpaceTypeName), enumType);
                        }
                        else
                        {
                            Debug.Assert(Helper.IsAssociationType(type));
                            _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(type.FullName), type);
                        }
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Creates new enum OSpace type built based on CLR <paramref name="enumType"/> and <paramref name="cspaceEnumType"/>
        /// </summary>
        /// <param name="enumType">CLR type to create OSpace type from.</param>
        /// <param name="cspaceEnumType">CSpace type used to get namespace and name for the newly created OSpace type.</param>
        /// <param name="newOSpaceType">
        /// New enum OSpace type built based on CLR <paramref name="enumType"/> and <paramref name="cspaceEnumType"/> or null
        /// if the type could not be built.
        /// </param>
        /// <returns><c>true</c> if the type was built successfully.<c>false</c> otherwise.</returns>
        private bool TryCreateEnumType(Type enumType, EnumType cspaceEnumType, out EdmType newOSpaceType)
        {
            Debug.Assert(enumType != null, "enumType != null");
            Debug.Assert(enumType.IsEnum, "enum type expected");
            Debug.Assert(cspaceEnumType != null, "cspaceEnumType != null");
            Debug.Assert(Helper.IsEnumType(cspaceEnumType), "Enum type expected");
            Debug.Assert(TypesMatchByConvention(enumType, cspaceEnumType), "The types passed as parameters don't match by convention.");

            newOSpaceType = null;

            // Check if the OSpace and CSpace enum type match
            if (!UnderlyingEnumTypesMatch(enumType, cspaceEnumType) || !EnumMembersMatch(enumType, cspaceEnumType))
            {
                return(false);
            }

            newOSpaceType = new ClrEnumType(enumType, cspaceEnumType.NamespaceName, cspaceEnumType.Name);
            SessionData.TypesInLoading.Add(enumType.FullName, newOSpaceType);

            return(true);
        }
        /// <summary>
        /// Load metadata of the given type - when you call this method, you should check and make sure that the type has
        /// edm attribute. If it doesn't,we won't load the type and it will be returned as null
        /// </summary>
        /// <param name="clrType"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private void LoadType(Type clrType)
        {
            Debug.Assert(clrType.Assembly == SourceAssembly, "Why are we loading a type that is not in our assembly?");
            Debug.Assert(!SessionData.TypesInLoading.ContainsKey(clrType.FullName), "Trying to load a type that is already loaded???");
            Debug.Assert(!clrType.IsGenericType, "Generic type is not supported");

            EdmType edmType = null;

            EdmTypeAttribute[] typeAttributes = (EdmTypeAttribute[])clrType.GetCustomAttributes(typeof(EdmTypeAttribute), false /*inherit*/);

            // the CLR doesn't allow types to have duplicate/multiple attribute declarations

            if (typeAttributes.Length != 0)
            {
                if (clrType.IsNested)
                {
                    SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.NestedClassNotSupported(clrType.FullName, clrType.Assembly.FullName), null));
                    return;
                }
                EdmTypeAttribute typeAttribute  = typeAttributes[0];
                string           cspaceTypeName = String.IsNullOrEmpty(typeAttribute.Name) ? clrType.Name : typeAttribute.Name;
                if (String.IsNullOrEmpty(typeAttribute.NamespaceName) && clrType.Namespace == null)
                {
                    SessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_TypeHasNoNamespace, edmType));
                    return;
                }

                string cspaceNamespaceName = String.IsNullOrEmpty(typeAttribute.NamespaceName) ? clrType.Namespace : typeAttribute.NamespaceName;

                if (typeAttribute.GetType() == typeof(EdmEntityTypeAttribute))
                {
                    edmType = new ClrEntityType(clrType, cspaceNamespaceName, cspaceTypeName);
                }
                else if (typeAttribute.GetType() == typeof(EdmComplexTypeAttribute))
                {
                    edmType = new ClrComplexType(clrType, cspaceNamespaceName, cspaceTypeName);
                }
                else
                {
                    Debug.Assert(typeAttribute is EdmEnumTypeAttribute, "Invalid type attribute encountered");

                    // Note that TryGetPrimitiveType() will return false not only for types that are not primitive
                    // but also for CLR primitive types that are valid underlying enum types in CLR but are not
                    // a valid Edm primitive types (e.g. ulong)
                    PrimitiveType underlyingEnumType;
                    if (!ClrProviderManifest.Instance.TryGetPrimitiveType(clrType.GetEnumUnderlyingType(), out underlyingEnumType))
                    {
                        SessionData.EdmItemErrors.Add(
                            new EdmItemError(
                                Strings.Validator_UnsupportedEnumUnderlyingType(clrType.GetEnumUnderlyingType().FullName),
                                edmType));

                        return;
                    }

                    edmType = new ClrEnumType(clrType, cspaceNamespaceName, cspaceTypeName);
                }
            }
            else
            {
                // not a type we are interested
                return;
            }

            Debug.Assert(!CacheEntry.ContainsType(edmType.Identity), "This type must not be already present in the list of types for this assembly");
            // Also add this to the list of the types for this assembly
            CacheEntry.TypesInAssembly.Add(edmType);

            // Add this to the known type map so we won't try to load it again
            SessionData.TypesInLoading.Add(clrType.FullName, edmType);

            // Load properties for structural type
            if (Helper.IsStructuralType(edmType))
            {
                //Load base type only for entity type - not sure if we will allow complex type inheritance
                if (Helper.IsEntityType(edmType))
                {
                    TrackClosure(clrType.BaseType);
                    AddTypeResolver(
                        () => edmType.BaseType = ResolveBaseType(clrType.BaseType));
                }

                // Load the properties for this type
                LoadPropertiesFromType((StructuralType)edmType);
            }

            return;
        }
        /// <summary>
        /// Creates new enum OSpace type built based on CLR <paramref name="enumType"/> and <paramref name="cspaceEnumType"/>
        /// </summary>
        /// <param name="enumType">CLR type to create OSpace type from.</param>
        /// <param name="cspaceEnumType">CSpace type used to get namespace and name for the newly created OSpace type.</param>
        /// <param name="newOSpaceType">
        /// New enum OSpace type built based on CLR <paramref name="enumType"/> and <paramref name="cspaceEnumType"/> or null
        /// if the type could not be built.
        /// </param>
        /// <returns><c>true</c> if the type was built successfully.<c>false</c> otherwise.</returns>
        private bool TryCreateEnumType(Type enumType, EnumType cspaceEnumType, out EdmType newOSpaceType)
        {
            Debug.Assert(enumType != null, "enumType != null");
            Debug.Assert(enumType.IsEnum, "enum type expected");
            Debug.Assert(cspaceEnumType != null, "cspaceEnumType != null");
            Debug.Assert(Helper.IsEnumType(cspaceEnumType), "Enum type expected");
            Debug.Assert(TypesMatchByConvention(enumType, cspaceEnumType), "The types passed as parameters don't match by convention.");

            newOSpaceType = null;

            // Check if the OSpace and CSpace enum type match
            if (!UnderlyingEnumTypesMatch(enumType, cspaceEnumType) || !EnumMembersMatch(enumType, cspaceEnumType))
            {
                return false;
            }

            newOSpaceType = new ClrEnumType(enumType, cspaceEnumType.NamespaceName, cspaceEnumType.Name);
            SessionData.TypesInLoading.Add(enumType.FullName, newOSpaceType);

            return true;
        }
コード例 #5
0
        /// <summary>
        /// Load metadata of the given type - when you call this method, you should check and make sure that the type has
        /// edm attribute. If it doesn't,we won't load the type and it will be returned as null
        /// </summary>
        /// <param name="clrType"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private void LoadType(Type clrType)
        {
            Debug.Assert(clrType.Assembly == SourceAssembly, "Why are we loading a type that is not in our assembly?");
            Debug.Assert(!SessionData.TypesInLoading.ContainsKey(clrType.FullName), "Trying to load a type that is already loaded???");
            Debug.Assert(!clrType.IsGenericType, "Generic type is not supported");

            EdmType edmType = null;

            EdmTypeAttribute[] typeAttributes = (EdmTypeAttribute[])clrType.GetCustomAttributes(typeof(EdmTypeAttribute), false /*inherit*/);

            // the CLR doesn't allow types to have duplicate/multiple attribute declarations

            if (typeAttributes.Length != 0)
            {
                if (clrType.IsNested)
                {
                    SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.NestedClassNotSupported(clrType.FullName, clrType.Assembly.FullName), null));
                    return;
                }
                EdmTypeAttribute typeAttribute = typeAttributes[0];
                string cspaceTypeName = String.IsNullOrEmpty(typeAttribute.Name) ? clrType.Name : typeAttribute.Name;
                if (String.IsNullOrEmpty(typeAttribute.NamespaceName) && clrType.Namespace == null)
                {
                    SessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_TypeHasNoNamespace, edmType));
                    return;
                }

                string cspaceNamespaceName = String.IsNullOrEmpty(typeAttribute.NamespaceName) ? clrType.Namespace : typeAttribute.NamespaceName;

                if (typeAttribute.GetType() == typeof(EdmEntityTypeAttribute))
                {
                    edmType = new ClrEntityType(clrType, cspaceNamespaceName, cspaceTypeName);
                }
                else if(typeAttribute.GetType() == typeof(EdmComplexTypeAttribute))
                {
                    edmType = new ClrComplexType(clrType, cspaceNamespaceName, cspaceTypeName);
                }
                else 
                {
                    Debug.Assert(typeAttribute is EdmEnumTypeAttribute, "Invalid type attribute encountered");

                    // Note that TryGetPrimitiveType() will return false not only for types that are not primitive 
                    // but also for CLR primitive types that are valid underlying enum types in CLR but are not 
                    // a valid Edm primitive types (e.g. ulong) 
                    PrimitiveType underlyingEnumType;
                    if (!ClrProviderManifest.Instance.TryGetPrimitiveType(clrType.GetEnumUnderlyingType(), out underlyingEnumType))
                    {
                        SessionData.EdmItemErrors.Add(
                            new EdmItemError(
                                Strings.Validator_UnsupportedEnumUnderlyingType(clrType.GetEnumUnderlyingType().FullName),
                                edmType));

                        return;
                    }

                    edmType = new ClrEnumType(clrType, cspaceNamespaceName, cspaceTypeName);
                }
            }
            else
            {
                // not a type we are interested
                return;
            }

            Debug.Assert(!CacheEntry.ContainsType(edmType.Identity), "This type must not be already present in the list of types for this assembly");
            // Also add this to the list of the types for this assembly
            CacheEntry.TypesInAssembly.Add(edmType);

            // Add this to the known type map so we won't try to load it again
            SessionData.TypesInLoading.Add(clrType.FullName, edmType);

            // Load properties for structural type
            if (Helper.IsStructuralType(edmType))
            {
                //Load base type only for entity type - not sure if we will allow complex type inheritance
                if (Helper.IsEntityType(edmType))
                {
                    TrackClosure(clrType.BaseType);
                    AddTypeResolver(
                        () => edmType.BaseType = ResolveBaseType(clrType.BaseType));
                }

                // Load the properties for this type
                LoadPropertiesFromType((StructuralType)edmType);
            }

            return;
        }