public Dictionary <string, Relationship> CreateRelationships(object objectGraph, string parentId, IResourceMapping resourceMapping, Context context) { var relationships = new Dictionary <string, Relationship>(); foreach (var linkMapping in resourceMapping.Relationships) { var relationshipName = linkMapping.RelationshipName; var rel = new Relationship(); var relLinks = new RelationshipLinks(); relLinks.Self = linkBuilder.RelationshipSelfLink(context, parentId, resourceMapping, linkMapping); relLinks.Related = linkBuilder.RelationshipRelatedLink(context, parentId, resourceMapping, linkMapping); if (!linkMapping.IsCollection) { string relatedId = null; object relatedInstance = null; if (linkMapping.RelatedResource != null) { relatedInstance = linkMapping.RelatedResource(objectGraph); if (relatedInstance != null) { relatedId = linkMapping.ResourceMapping.IdGetter(relatedInstance).ToString(); } } if (linkMapping.RelatedResourceId != null && relatedId == null) { var id = linkMapping.RelatedResourceId(objectGraph); if (id != null) { relatedId = id.ToString(); } } if (linkMapping.InclusionRule != ResourceInclusionRules.ForceOmit) { // Generating resource linkage for to-one relationships if (relatedInstance != null) { rel.Data = new SingleResourceIdentifier { Id = relatedId, Type = configuration.GetMapping(relatedInstance.GetType()).ResourceType // This allows polymorphic (subtyped) resources to be fully represented } } ; else if (relatedId == null || linkMapping.InclusionRule == ResourceInclusionRules.ForceInclude) { rel.Data = new NullResourceIdentifier(); // two-state null case, see NullResourceIdentifier summary } } } else { IEnumerable relatedInstance = null; if (linkMapping.RelatedResource != null) { relatedInstance = (IEnumerable)linkMapping.RelatedResource(objectGraph); } // Generating resource linkage for to-many relationships if (linkMapping.InclusionRule == ResourceInclusionRules.ForceInclude && relatedInstance == null) { rel.Data = new MultipleResourceIdentifiers(); } if (linkMapping.InclusionRule != ResourceInclusionRules.ForceOmit && relatedInstance != null) { var idGetter = linkMapping.ResourceMapping.IdGetter; var identifiers = relatedInstance .Cast <object>() .Select(o => new SingleResourceIdentifier { Id = idGetter(o).ToString(), Type = configuration.GetMapping(o.GetType()).ResourceType // This allows polymorphic (subtyped) resources to be fully represented }); rel.Data = new MultipleResourceIdentifiers(identifiers); } // If data is present, count meta attribute is added for convenience if (rel.Data != null) { rel.Meta = new Dictionary <string, string> { { MetaCountAttribute, ((MultipleResourceIdentifiers)rel.Data).Count.ToString() } } } ; } if (relLinks.Self != null || relLinks.Related != null) { rel.Links = relLinks; } if (rel.Data != null || rel.Links != null) { relationships.Add(relationshipName, rel); } } return(relationships.Any() ? relationships : null); }