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); } } } }
/// <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); } }
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); } }