private static Link CreateResourceRelationshipLink(IHypermediaContext hypermediaContext, IResourcePathContext resourcePathContext, IResourceType resourceType, object clrResource, bool addRelationshipsPathSegment, IRelationshipInfo relationship, Meta apiRelationshipLinkMeta) { Contract.Requires(hypermediaContext != null); Contract.Requires(resourcePathContext != null); Contract.Requires(resourceType != null); Contract.Requires(clrResource != null); Contract.Requires(relationship != null); var clrResourceType = resourceType.ClrType; var urlBuilderConfiguration = hypermediaContext.GetUrlBuilderConfiguration(clrResourceType); var apiId = resourceType.GetApiId(clrResource); var apiResourcePath = resourcePathContext.GetResourceSelfPath(apiId); var apiRelationshipRelPathSegment = relationship.ApiRelPathSegment; var apiRelationshipLinkHRef = UrlBuilder.Create(urlBuilderConfiguration) .Path(apiResourcePath) .Path(Keywords.Relationships, addRelationshipsPathSegment) .Path(apiRelationshipRelPathSegment) .Build(); var apiRelationshipLink = new Link { HRef = apiRelationshipLinkHRef, Meta = apiRelationshipLinkMeta }; return(apiRelationshipLink); }
public bool TryGetRelationshipInfo(string rel, out IRelationshipInfo relationship) { Contract.Requires(String.IsNullOrWhiteSpace(rel) == false); relationship = this.Collection.SingleOrDefault(x => x.Rel == rel); return(relationship != null); }
private static void AddPath(IResourceType resourceType, Type clrResourceType, string apiId, IRelationshipInfo nextRelationship, ref List <IHypermediaPath> resourceBasePath, ref ResourcePathMode resourcePathMode, ref IRelationshipInfo resourcePreviousRelationship) { Contract.Requires(resourceType != null); Contract.Requires(clrResourceType != null); Contract.Requires(String.IsNullOrWhiteSpace(apiId) == false); Contract.Requires(nextRelationship != null); Contract.Requires(resourceBasePath != null); if (resourcePreviousRelationship == null) { var apiCollectionPathSegment = resourceType.HypermediaInfo.ApiCollectionPathSegment; var resourceHypermediaPath = new ResourceHypermediaPath(clrResourceType, apiCollectionPathSegment, apiId); resourceBasePath.Add(resourceHypermediaPath); resourcePathMode = ResourcePathMode.IncludeApiId; resourcePreviousRelationship = nextRelationship; return; } var previousRelationshipCardinality = resourcePreviousRelationship.ToCardinality; var apiRelationshipRelPathSegment = resourcePreviousRelationship.ApiRelPathSegment; switch (previousRelationshipCardinality) { case RelationshipCardinality.ToOne: { var toOneResourceHypermediaPath = new ToOneResourceHypermediaPath(clrResourceType, apiRelationshipRelPathSegment); resourceBasePath.Add(toOneResourceHypermediaPath); resourcePathMode = ResourcePathMode.IgnoreApiId; } break; case RelationshipCardinality.ToMany: { var toManyResourceHypermediaPath = new ToManyResourceHypermediaPath(clrResourceType, apiRelationshipRelPathSegment, apiId); resourceBasePath.Add(toManyResourceHypermediaPath); resourcePathMode = ResourcePathMode.IncludeApiId; } break; default: { var detail = InfrastructureErrorStrings.InternalErrorExceptionDetailUnknownEnumerationValue .FormatWith(typeof(RelationshipCardinality).Name, previousRelationshipCardinality); throw new InternalErrorException(detail); } } resourcePreviousRelationship = nextRelationship; }
// PUBLIC METHODS /////////////////////////////////////////////////// #region Assert Methods public static void Equal(IRelationshipInfo expected, IRelationshipInfo actual) { if (expected == null) { Assert.Null(actual); return; } Assert.NotNull(actual); Assert.Equal(expected.Rel, actual.Rel); Assert.Equal(expected.ApiRelPathSegment, actual.ApiRelPathSegment); Assert.Equal(expected.ToCardinality, actual.ToCardinality); Assert.Equal(expected.ToClrType, actual.ToClrType); Assert.Equal(expected.ToCanonicalRelPathMode, actual.ToCanonicalRelPathMode); }
public Relationship(MemberInfo member, IRelationshipInfo relationshipInfo) { Member = member; MemberType = ReflectionHelper.GetMemberType(member); // Try to determine the RelationshipType if (relationshipInfo.RelationType == RelationshipTypes.AutoDetect) { if (typeof(ICollection).IsAssignableFrom(MemberType)) { relationshipInfo.RelationType = RelationshipTypes.Many; } else { relationshipInfo.RelationType = RelationshipTypes.One; } } // Try to determine the EntityType if (relationshipInfo.EntityType == null) { if (relationshipInfo.RelationType == RelationshipTypes.Many) { if (MemberType.IsGenericType) { // Assume a Collection<T> or List<T> and return T relationshipInfo.EntityType = MemberType.GetGenericArguments()[0]; } else { throw new ArgumentException(string.Format( "The DataMapper could not determine the RelationshipAttribute EntityType for {0}.", MemberType.Name)); } } else { relationshipInfo.EntityType = MemberType; } } RelationshipInfo = relationshipInfo; Setter = MapRepository.Instance.ReflectionStrategy.BuildSetter(member.DeclaringType, member.Name); }
private static Links CreateResourceRelationshipLinks(IHypermediaContext hypermediaContext, IResourcePathContext resourcePathContext, IResourceType resourceType, object clrResource, IRelationshipInfo relationship, IRelationshipContext relationshipContext) { Contract.Requires(hypermediaContext != null); Contract.Requires(resourcePathContext != null); Contract.Requires(resourceType != null); Contract.Requires(clrResource != null); Contract.Requires(relationship != null); Contract.Requires(relationshipContext != null); var apiRelationshipHasLinks = relationshipContext.HasLinks(); if (!apiRelationshipHasLinks) { return(null); } var links = relationshipContext.LinkContexts; var apiRelationshipRelToLinkDictionary = links .Select(x => { var rel = x.Rel; var meta = x.Meta; var isSelfLink = String.Compare(Keywords.Self, rel, StringComparison.Ordinal) == 0; var link = CreateResourceRelationshipLink(hypermediaContext, resourcePathContext, resourceType, clrResource, isSelfLink, relationship, meta); return(new Tuple <string, Link>(rel, link)); }) .ToDictionary(x => x.Item1, x => x.Item2); var apiRelationshipLinks = new Links(apiRelationshipRelToLinkDictionary); return(apiRelationshipLinks); }
private static Relationship CreateResourceRelationship(Links apiRelationshipLinks, IResourceType resourceType, IRelationshipInfo relationship, IRelationshipContext relationshipContext) { Contract.Requires(resourceType != null); Contract.Requires(relationship != null); Contract.Requires(relationshipContext != null); var apiRelationshipToCardinality = relationship.ToCardinality; var apiRelationshipMeta = relationshipContext.Meta; var apiRelationshipType = relationshipContext.GetRelationshipType(); switch (apiRelationshipType) { case RelationshipType.Relationship: { var apiRelationship = new Relationship { Links = apiRelationshipLinks, Meta = apiRelationshipMeta }; return(apiRelationship); } case RelationshipType.ToOneRelationship: { if (apiRelationshipToCardinality != RelationshipCardinality.ToOne) { var apiRel = relationshipContext.Rel; var fromClrResourceTypeName = resourceType.ClrType.Name; var toClrResourceTypeName = relationship.ToClrType.Name; var detail = ServerErrorStrings .DocumentBuildExceptionDetailBuildResourceRelationshipCardinalityMismatch .FormatWith(apiRel, fromClrResourceTypeName, toClrResourceTypeName, RelationshipCardinality.ToOne, apiRelationshipToCardinality); throw new DocumentBuildException(detail); } var apiToOneResourceLinkage = relationshipContext.GetToOneResourceLinkage(); var apiRelationship = new ToOneRelationship { Links = apiRelationshipLinks, Data = apiToOneResourceLinkage, Meta = apiRelationshipMeta }; return(apiRelationship); } case RelationshipType.ToManyRelationship: { if (apiRelationshipToCardinality != RelationshipCardinality.ToMany) { var apiRel = relationshipContext.Rel; var fromClrResourceTypeName = resourceType.ClrType.Name; var toClrResourceTypeName = relationship.ToClrType.Name; var detail = ServerErrorStrings .DocumentBuildExceptionDetailBuildResourceRelationshipCardinalityMismatch .FormatWith(apiRel, fromClrResourceTypeName, toClrResourceTypeName, RelationshipCardinality.ToMany, apiRelationshipToCardinality); throw new DocumentBuildException(detail); } var apiToManyResourceLinkage = relationshipContext.GetToManyResourceLinkage() .SafeToList(); var apiRelationship = new ToManyRelationship { Links = apiRelationshipLinks, Data = apiToManyResourceLinkage, Meta = apiRelationshipMeta }; return(apiRelationship); } default: { var detail = InfrastructureErrorStrings.InternalErrorExceptionDetailUnknownEnumerationValue .FormatWith(typeof(RelationshipType).Name, apiRelationshipType); throw new InternalErrorException(detail); } } }
public void TestResourceTypeGetRelationshipInfo(string name, bool relationshipExists, IResourceType resourceType, string rel, IRelationshipInfo expected) { this.Output.WriteLine("Test Name: {0}", name); this.Output.WriteLine(String.Empty); // Arrange // Act if (!relationshipExists) { Assert.Throws <ServiceModelException>(() => resourceType.GetRelationshipInfo(rel)); return; } var actual = resourceType.GetRelationshipInfo(rel); // Assert RelationshipInfoAssert.Equal(expected, actual); }
public void TestResourceTypeTryGetRelationshipInfo(string name, bool attributeExists, IResourceType resourceType, string clrPropertyName, IRelationshipInfo expected) { this.Output.WriteLine("Test Name: {0}", name); this.Output.WriteLine(String.Empty); // Arrange // Act IRelationshipInfo actual; var actualExists = resourceType.TryGetRelationshipInfo(clrPropertyName, out actual); // Assert if (!attributeExists) { Assert.False(actualExists); Assert.Null(actual); return; } Assert.True(actualExists); Assert.NotNull(actual); RelationshipInfoAssert.Equal(expected, actual); }
public Relationship(MemberInfo member, IRelationshipInfo relationshipInfo) { Member = member; MemberType = ReflectionHelper.GetMemberType(member); // Try to determine the RelationshipType if (relationshipInfo.RelationType == RelationshipTypes.AutoDetect) { if (member.MemberType == MemberTypes.Field && MemberType == typeof(object)) { // Handles dynamic member fields that are lazy loaded var prop = DataHelper.FindPropertyForBackingField(member.ReflectedType, member); if (prop != null) { if (typeof(System.Collections.IEnumerable).IsAssignableFrom(prop.ReturnType)) relationshipInfo.RelationType = RelationshipTypes.Many; else relationshipInfo.RelationType = RelationshipTypes.One; } } else { if (typeof(System.Collections.IEnumerable).IsAssignableFrom(MemberType)) relationshipInfo.RelationType = RelationshipTypes.Many; else relationshipInfo.RelationType = RelationshipTypes.One; } } // Try to determine the EntityType if (relationshipInfo.EntityType == null) { if (relationshipInfo.RelationType == RelationshipTypes.Many) { if (MemberType.IsGenericType) { // Assume a Collection<T> or List<T> and return T relationshipInfo.EntityType = MemberType.GetGenericArguments()[0]; } else if (MemberType == typeof(object)) { relationshipInfo.EntityType = typeof(object); } else { throw new ArgumentException(string.Format( "The DataMapper could not determine the RelationshipAttribute EntityType for {0}.", MemberType.Name)); } } else { relationshipInfo.EntityType = MemberType; } } RelationshipInfo = relationshipInfo; Setter = MapRepository.Instance.ReflectionStrategy.BuildSetter(member.DeclaringType, member.Name); }
public Relationship(MemberInfo member, IRelationshipInfo relationshipInfo) { Member = member; MemberType = ReflectionHelper.GetMemberType(member); // Try to determine the RelationshipType if (relationshipInfo.RelationType == RelationshipTypes.AutoDetect) { if (member.MemberType == MemberTypes.Field && MemberType == typeof(object)) { // Handles dynamic member fields that are lazy loaded var prop = DataHelper.FindPropertyForBackingField(member.ReflectedType, member); if (prop != null) { if (typeof(System.Collections.IEnumerable).IsAssignableFrom(prop.ReturnType)) { relationshipInfo.RelationType = RelationshipTypes.Many; } else { relationshipInfo.RelationType = RelationshipTypes.One; } } } else { if (typeof(System.Collections.IEnumerable).IsAssignableFrom(MemberType)) { relationshipInfo.RelationType = RelationshipTypes.Many; } else { relationshipInfo.RelationType = RelationshipTypes.One; } } } // Try to determine the EntityType if (relationshipInfo.EntityType == null) { if (relationshipInfo.RelationType == RelationshipTypes.Many) { if (MemberType.IsGenericType) { // Assume a Collection<T> or List<T> and return T relationshipInfo.EntityType = MemberType.GetGenericArguments()[0]; } else if (MemberType == typeof(object)) { relationshipInfo.EntityType = typeof(object); } else { throw new ArgumentException(string.Format( "The DataMapper could not determine the RelationshipAttribute EntityType for {0}.", MemberType.Name)); } } else { relationshipInfo.EntityType = MemberType; } } RelationshipInfo = relationshipInfo; Setter = MapRepository.Instance.ReflectionStrategy.BuildSetter(member.DeclaringType, member.Name); }
private static Tuple <ICollection <IHypermediaPath>, ResourcePathMode> CreateResourcePathParts(Type clrResourceType, IResourceType resourceType, ICollection <IHypermediaPath> resourceBasePath, IRelationshipInfo resourcePreviousRelationship) { Contract.Requires(clrResourceType != null); Contract.Requires(resourceType != null); ResourcePathMode resourcePathMode; if (resourcePreviousRelationship == null) { var apiCollectionPathSegment = resourceType.HypermediaInfo.ApiCollectionPathSegment; var hypermediaPath = default(IHypermediaPath); if (!resourceType.IsSingleton()) { hypermediaPath = new ResourceCollectionHypermediaPath(clrResourceType, apiCollectionPathSegment); resourcePathMode = ResourcePathMode.IncludeApiId; } else { hypermediaPath = new SingletonHypermediaPath(clrResourceType, apiCollectionPathSegment); resourcePathMode = ResourcePathMode.IgnoreApiId; } resourceBasePath.Add(hypermediaPath); } else { var previousRelationshipCardinality = resourcePreviousRelationship.ToCardinality; var apiRelationshipRelPathSegment = resourcePreviousRelationship.ApiRelPathSegment; switch (previousRelationshipCardinality) { case RelationshipCardinality.ToOne: { var toOneResourceHypermediaPath = new ToOneResourceHypermediaPath(clrResourceType, apiRelationshipRelPathSegment); resourceBasePath.Add(toOneResourceHypermediaPath); resourcePathMode = ResourcePathMode.IgnoreApiId; } break; case RelationshipCardinality.ToMany: { var toManyResourceHypermediaPath = new ToManyResourceCollectionHypermediaPath(clrResourceType, apiRelationshipRelPathSegment); resourceBasePath.Add(toManyResourceHypermediaPath); resourcePathMode = ResourcePathMode.IncludeApiId; } break; default: { var detail = InfrastructureErrorStrings.InternalErrorExceptionDetailUnknownEnumerationValue .FormatWith(typeof(RelationshipCardinality).Name, previousRelationshipCardinality); throw new InternalErrorException(detail); } } } var resourcePathParts = new Tuple <ICollection <IHypermediaPath>, ResourcePathMode>(resourceBasePath, resourcePathMode); return(resourcePathParts); }
public bool TryGetRelationshipInfo(string rel, out IRelationshipInfo relationshipInfo) { relationshipInfo = null; return(this.RelationshipsInfo != null && this.RelationshipsInfo.TryGetRelationshipInfo(rel, out relationshipInfo)); }