Exemple #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 (var entry in _knownAssemblies.GetEntries(_loaderFactory, edmItemCollection))
                {
                    foreach (var type in entry.CacheEntry.TypesInAssembly.OfType <EdmType>())
                    {
                        if (Helper.IsEntityType(type))
                        {
                            var entityType = (ClrEntityType)type;
                            _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(entityType.CSpaceTypeName), entityType);
                        }
                        else if (Helper.IsComplexType(type))
                        {
                            var complexType = (ClrComplexType)type;
                            _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(complexType.CSpaceTypeName), complexType);
                        }
                        else if (Helper.IsEnumType(type))
                        {
                            var 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);
                        }
                    }
                }
            }
        }
        public virtual IEnumerable <AssociationType> GetAllRelationshipTypesExpensiveWay(
            Assembly assembly)
        {
            Dictionary <string, EdmType> typesInLoading = this.LoadTypesExpensiveWay(assembly);

            if (typesInLoading != null)
            {
                foreach (EdmType type in typesInLoading.Values)
                {
                    if (Helper.IsAssociationType(type))
                    {
                        yield return((AssociationType)type);
                    }
                }
            }
        }
Exemple #3
0
        /// <summary>
        ///     internal static method to get all the AssociationTypes from an assembly
        /// </summary>
        /// <param name="assembly"> The assembly from which to load relationship types </param>
        /// <returns> An enumeration of OSpace AssociationTypes that are present in this assembly </returns>
        internal static IEnumerable <AssociationType> GetAllRelationshipTypesExpensiveWay(Assembly assembly)
        {
            var typesInLoading = LoadTypesExpensiveWay(assembly);

            if (typesInLoading != null)
            {
                // Iterate through the EdmTypes looking for AssociationTypes
                foreach (var edmType in typesInLoading.Values)
                {
                    if (Helper.IsAssociationType(edmType))
                    {
                        yield return((AssociationType)edmType);
                    }
                }
            }
            yield break;
        }
        public virtual IEnumerable <AssociationType> GetAllRelationshipTypesExpensiveWay(Assembly assembly)
        {
            DebugCheck.NotNull(assembly);

            var typesInLoading = LoadTypesExpensiveWay(assembly);

            if (typesInLoading != null)
            {
                // Iterate through the EdmTypes looking for AssociationTypes
                foreach (var edmType in typesInLoading.Values)
                {
                    if (Helper.IsAssociationType(edmType))
                    {
                        yield return((AssociationType)edmType);
                    }
                }
            }
        }
        internal void ResolveNavigationProperty(StructuralType declaringType, PropertyInfo propertyInfo)
        {
            // EdmScalarPropertyAttribute, EdmComplexPropertyAttribute and EdmRelationshipNavigationPropertyAttribute
            // are all EdmPropertyAttributes that we need to process. If the current property is not an EdmPropertyAttribute
            // we will just ignore it and skip to the next property.
            var relationshipPropertyAttributes = propertyInfo.GetCustomAttributes <EdmRelationshipNavigationPropertyAttribute>(inherit: false);

            Debug.Assert(relationshipPropertyAttributes.Count() == 1, "There should be exactly one property for every navigation property");

            // The only valid return types from navigation properties are:
            //     (1) EntityType
            //     (2) CollectionType containing valid EntityType

            // If TryGetLoadedType returned false, it could mean that we couldn't validate any part of the type, or it could mean that it's a generic
            // where the main generic type was validated, but the generic type parameter was not. We can't tell the difference, so just fail
            // with the same error message in both cases. The user will have to figure out which part of the type is wrong.
            // We can't just rely on checking for a generic because it can lead to a scenario where we report that the type parameter is invalid
            // when really it's the main generic type. That is more confusing than reporting the full name and letting the user determine the problem.
            EdmType propertyType;

            if (!TryGetLoadedType(propertyInfo.PropertyType, out propertyType)
                ||
                !(propertyType.BuiltInTypeKind == BuiltInTypeKind.EntityType ||
                  propertyType.BuiltInTypeKind == BuiltInTypeKind.CollectionType))
            {
                // Once an error is detected the property does not need to be validated further, just add to the errors
                // collection and continue with the next property. The failure will cause an exception to be thrown later during validation of all of the types.
                SessionData.EdmItemErrors.Add(
                    new EdmItemError(
                        Strings.Validator_OSpace_InvalidNavPropReturnType(
                            propertyInfo.Name, propertyInfo.DeclaringType.FullName, propertyInfo.PropertyType.FullName)));
                return;
            }
            // else we have a valid EntityType or CollectionType that contains EntityType. ResolveNonSchemaType enforces that a collection type
            // must contain an EntityType, and if it doesn't, propertyType will be null here. If propertyType is EntityType or CollectionType we know it is valid

            // Expecting EdmRelationshipNavigationPropertyAttribute to have AllowMultiple=False, so only look at first element in the attribute array

            var attribute = (EdmRelationshipNavigationPropertyAttribute)relationshipPropertyAttributes.First();

            EdmMember member = null;
            EdmType   type;

            if (SessionData.TypesInLoading.TryGetValue(attribute.RelationshipNamespaceName + "." + attribute.RelationshipName, out type)
                &&
                Helper.IsAssociationType(type))
            {
                var relationshipType = (AssociationType)type;
                if (relationshipType != null)
                {
                    // The return value of this property has been verified, so create the property now
                    var navigationProperty = new NavigationProperty(propertyInfo.Name, TypeUsage.Create(propertyType));
                    navigationProperty.RelationshipType = relationshipType;
                    member = navigationProperty;

                    if (relationshipType.Members[0].Name
                        == attribute.TargetRoleName)
                    {
                        navigationProperty.ToEndMember   = (RelationshipEndMember)relationshipType.Members[0];
                        navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[1];
                    }
                    else if (relationshipType.Members[1].Name
                             == attribute.TargetRoleName)
                    {
                        navigationProperty.ToEndMember   = (RelationshipEndMember)relationshipType.Members[1];
                        navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[0];
                    }
                    else
                    {
                        SessionData.EdmItemErrors.Add(
                            new EdmItemError(
                                Strings.TargetRoleNameInNavigationPropertyNotValid(
                                    propertyInfo.Name, propertyInfo.DeclaringType.FullName, attribute.TargetRoleName,
                                    attribute.RelationshipName)));
                        member = null;
                    }

                    if (member != null
                        &&
                        ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType != declaringType.ClrType)
                    {
                        SessionData.EdmItemErrors.Add(
                            new EdmItemError(
                                Strings.NavigationPropertyRelationshipEndTypeMismatch(
                                    declaringType.FullName,
                                    navigationProperty.Name,
                                    relationshipType.FullName,
                                    navigationProperty.FromEndMember.Name,
                                    ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType)));
                        member = null;
                    }
                }
            }
            else
            {
                SessionData.EdmItemErrors.Add(
                    new EdmItemError(
                        Strings.RelationshipNameInNavigationPropertyNotValid(
                            propertyInfo.Name, propertyInfo.DeclaringType.FullName, attribute.RelationshipName)));
            }

            if (member != null)
            {
                declaringType.AddMember(member);
            }
        }
Exemple #6
0
        internal void ResolveNavigationProperty(StructuralType declaringType, PropertyInfo propertyInfo)
        {
            IEnumerable <EdmRelationshipNavigationPropertyAttribute> customAttributes = propertyInfo.GetCustomAttributes <EdmRelationshipNavigationPropertyAttribute>(false);
            EdmType edmType;

            if (!this.TryGetLoadedType(propertyInfo.PropertyType, out edmType) || edmType.BuiltInTypeKind != BuiltInTypeKind.EntityType && edmType.BuiltInTypeKind != BuiltInTypeKind.CollectionType)
            {
                this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_OSpace_InvalidNavPropReturnType((object)propertyInfo.Name, (object)propertyInfo.DeclaringType.FullName, (object)propertyInfo.PropertyType.FullName)));
            }
            else
            {
                EdmRelationshipNavigationPropertyAttribute propertyAttribute = customAttributes.First <EdmRelationshipNavigationPropertyAttribute>();
                EdmMember member = (EdmMember)null;
                EdmType   type;
                if (this.SessionData.TypesInLoading.TryGetValue(propertyAttribute.RelationshipNamespaceName + "." + propertyAttribute.RelationshipName, out type) && Helper.IsAssociationType(type))
                {
                    AssociationType associationType = (AssociationType)type;
                    if (associationType != null)
                    {
                        NavigationProperty navigationProperty = new NavigationProperty(propertyInfo.Name, TypeUsage.Create(edmType));
                        navigationProperty.RelationshipType = (RelationshipType)associationType;
                        member = (EdmMember)navigationProperty;
                        if (associationType.Members[0].Name == propertyAttribute.TargetRoleName)
                        {
                            navigationProperty.ToEndMember   = (RelationshipEndMember)associationType.Members[0];
                            navigationProperty.FromEndMember = (RelationshipEndMember)associationType.Members[1];
                        }
                        else if (associationType.Members[1].Name == propertyAttribute.TargetRoleName)
                        {
                            navigationProperty.ToEndMember   = (RelationshipEndMember)associationType.Members[1];
                            navigationProperty.FromEndMember = (RelationshipEndMember)associationType.Members[0];
                        }
                        else
                        {
                            this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.TargetRoleNameInNavigationPropertyNotValid((object)propertyInfo.Name, (object)propertyInfo.DeclaringType.FullName, (object)propertyAttribute.TargetRoleName, (object)propertyAttribute.RelationshipName)));
                            member = (EdmMember)null;
                        }
                        if (member != null && ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType != declaringType.ClrType)
                        {
                            this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.NavigationPropertyRelationshipEndTypeMismatch((object)declaringType.FullName, (object)navigationProperty.Name, (object)associationType.FullName, (object)navigationProperty.FromEndMember.Name, (object)((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType)));
                            member = (EdmMember)null;
                        }
                    }
                }
                else
                {
                    this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.RelationshipNameInNavigationPropertyNotValid((object)propertyInfo.Name, (object)propertyInfo.DeclaringType.FullName, (object)propertyAttribute.RelationshipName)));
                }
                if (member == null)
                {
                    return;
                }
                declaringType.AddMember(member);
            }
        }