예제 #1
0
        /// <summary>
        /// Attempts to instatiate an object of type <paramref name="targetType"/> with data from <paramref name="resourceObject"/> using the <paramref name="apiResource"/>.
        /// </summary>
        /// <param name="resourceObject"></param>
        /// <param name="apiResource"></param>
        /// <param name="targetType"></param>
        /// <returns></returns>
        public static object ToObject(this JsonApiResourceObject resourceObject, JsonApiResource apiResource, Type targetType)
        {
            var result = Activator.CreateInstance(targetType);

            // extract id
            if (!string.IsNullOrWhiteSpace(resourceObject.Id))
            {
                var idProp = targetType.GetProperty(apiResource.IdProperty);
                if (idProp != null)
                {
                    var idObject = BtbrdCoreIdConverters.ConvertFromString(resourceObject.Id, idProp.PropertyType);
                    idProp.SetValueFast(result, idObject);
                }
            }

            // TODO: better iterate over attributes and relations defined in the apiresource

            // extract attributes
            if (resourceObject.Attributes != null)
            {
                foreach (var attribute in resourceObject.Attributes)
                {
                    var resourceAttribute = apiResource.Attributes.Where(a => a.Name == attribute.Key).FirstOrDefault();
                    if (resourceAttribute == null)
                    {
                        continue;
                    }

                    var targetProperty = targetType.GetProperty(resourceAttribute.PropertyName);
                    if (targetProperty == null)
                    {
                        continue;
                    }

                    // Not handled: ienumerables of datetime,datetimeoffset and nullables

                    var underlying = Nullable.GetUnderlyingType(targetProperty.PropertyType) ?? targetProperty.PropertyType;

                    var value = attribute.Value;
                    if (value != null)
                    {
                        if (underlying == typeof(DateTime))
                        {
                            value = DateTime.Parse(value.ToString());
                        }
                        else if (underlying == typeof(DateTimeOffset))
                        {
                            value = DateTimeOffset.Parse(value.ToString());
                        }
                        else if (underlying.IsEnum)
                        {
                            value = Enum.ToObject(underlying, Convert.ChangeType(value, Enum.GetUnderlyingType(underlying)));
                        }
                        else
                        {
                            value = Convert.ChangeType(value, underlying);
                        }
                    }

                    targetProperty.SetValueFast(result, value);
                }
            }

            // extract relationships
            if (resourceObject.Relationships != null)
            {
                foreach (var relationship in resourceObject.Relationships)
                {
                    var relationResource = apiResource.Relationships.Where(r => r.Name == relationship.Key).FirstOrDefault();
                    if (relationResource == null)
                    {
                        continue;
                    }
                    if (relationResource.Kind == RelationshipKind.BelongsTo)
                    {
                        var relationshipObject = relationship.Value as JsonApiToOneRelationshipObject;
                        if (!string.IsNullOrWhiteSpace(relationshipObject.Data?.Id))
                        {
                            var idProp = targetType.GetProperty(relationResource.IdPropertyName);
                            if (idProp != null)
                            {
                                var idObject = BtbrdCoreIdConverters.ConvertFromString(relationshipObject.Data.Id, idProp.PropertyType);
                                idProp.SetValueFast(result, idObject);
                            }
                        }
                    }
                    else
                    {
                        var idProp = targetType.GetProperty(relationResource.IdPropertyName)
                                     ?? throw new Exception($"{nameof(JsonApiResourceObjectExtensions)}: Could not find relation property {relationResource.IdPropertyName}");

                        // get type of the id (e.g. long, string, ..)
                        Type innerType;
                        if (idProp.PropertyType.IsArray)
                        {
                            innerType = idProp.PropertyType.GetElementType();
                        }
                        else if (idProp.PropertyType.IsNonStringEnumerable())
#if (NET40)
                        { innerType = idProp.PropertyType.GetGenericArguments()[0]; }
#else
                        { innerType = idProp.PropertyType.GenericTypeArguments[0]; }
#endif
                        else
                        {
                            throw new Exception($"{nameof(JsonApiResourceObjectExtensions)}: Trying to read the relation, could not find element-type of type {idProp.PropertyType.FullName}.");
                        }

                        if (!(relationship.Value is JsonApiToManyRelationshipObject relationshipObject))
                        {
                            throw new Exception($"{nameof(JsonApiResourceObjectExtensions)}: Expected a {nameof(JsonApiToManyRelationshipObject)}, found {relationship.Value?.GetType().FullName ?? "null"}");
                        }

                        // create List instance
                        //   get the below defined method GetIdCollection for T=innerType
                        //   and executes it.
                        var instance = (typeof(JsonApiResourceObjectExtensions)
                                        .GetMethod(nameof(GetIdCollection))
                                        ?.MakeGenericMethod(innerType) ?? throw new Exception($"{nameof(JsonApiResourceObjectExtensions)}: Method {nameof(GetIdCollection)} not found."))
                                       .Invoke(null, new object[]
                        {
                            /* IEnumerable<JsonApiResourceIdentifierObject> ids : */ relationshipObject.Data,
                            /* bool makeArray : */ idProp.PropertyType.IsArray
                        });

                        idProp.SetValueFast(result, instance);
                    }
 public static JsonApiResourceObject GetResource(this JsonApiResourceObjectDictionary resourceDictionary, object id, Type type)
 {
     return(resourceDictionary.GetResource(BtbrdCoreIdConverters.ConvertToString(id), type.GetJsonApiClassName()));
 }
예제 #3
0
        public static string GetIdAsString(this IJsonApiDataModel obj)
        {
            var info = obj.GetType().GetProperty("Id");

            return(BtbrdCoreIdConverters.ConvertToString(info.GetValueFast(obj)));
        }
예제 #4
0
        public static void SetIdFromString(this IJsonApiDataModel obj, string stringId)
        {
            var info = obj.GetType().GetProperty("Id");

            info.SetValueFast(obj, BtbrdCoreIdConverters.ConvertFromString(stringId, info.PropertyType));
        }
 public static JsonApiResourceObject GetResource(this JsonApiResourceObjectDictionary resourceDictionary, object id, JsonApiResource apiResource)
 {
     return(resourceDictionary.GetResource(BtbrdCoreIdConverters.ConvertToString(id), apiResource.ResourceType));
 }