/// <summary> /// Creates a cacheable model field representation from a PropertyInfo /// </summary> /// <param name="prop">The property</param> /// <returns>A model field represenation</returns> protected virtual ResourceTypeField CreateResourceTypeField(PropertyInfo prop) { var jsonKey = _namingConventions.GetFieldNameForProperty(prop); var type = prop.PropertyType; if (prop.PropertyType.CanWriteAsJsonApiAttribute() || prop.GetCustomAttributes <SerializeAsComplexAttribute>().Any()) { var converter = GetValueConverterForProperty(prop); return(new ResourceTypeAttribute(converter, prop, jsonKey)); } var selfLinkTemplateAttribute = prop.GetCustomAttributes().OfType <RelationshipLinkTemplate>().FirstOrDefault(); var selfLinkTemplate = selfLinkTemplateAttribute?.TemplateString; var relatedResourceLinkTemplateAttribute = prop.GetCustomAttributes().OfType <RelatedResourceLinkTemplate>().FirstOrDefault(); var relatedResourceLinkTemplate = relatedResourceLinkTemplateAttribute?.TemplateString; var isToMany = type.IsArray || (type.GetInterfaces().Contains(typeof(System.Collections.IEnumerable)) && type.IsGenericType); var linkSettingsAttribute = prop.GetCustomAttributes().OfType <LinkSettingsAttribute>().FirstOrDefault(); var serializeRelationshipLink = linkSettingsAttribute == null || linkSettingsAttribute.SerializeRelationshipLink; var serializeRelatedResourceLink = linkSettingsAttribute == null || linkSettingsAttribute.SerializeRelatedResourceLink; if (!isToMany) { return(new ToOneResourceTypeRelationship(prop, jsonKey, type, selfLinkTemplate, relatedResourceLinkTemplate, serializeRelationshipLink, serializeRelatedResourceLink)); } var relatedType = type.IsGenericType ? type.GetGenericArguments()[0] : type.GetElementType(); return(new ToManyResourceTypeRelationship(prop, jsonKey, relatedType, selfLinkTemplate, relatedResourceLinkTemplate, serializeRelationshipLink, serializeRelatedResourceLink)); }