Ejemplo n.º 1
0
        public IResourceTypeRegistration BuildRegistration(Type type, string resourceTypeName = null,
                                                           Func <ParameterExpression, string, BinaryExpression> filterByIdFactory = null,
                                                           Func <ParameterExpression, Expression> sortByIdFactory = null)
        {
            if (resourceTypeName == null)
            {
                resourceTypeName = _namingConventions.GetResourceTypeNameForType(type);
            }

            var fieldMap = new Dictionary <string, ResourceTypeField>();

            var idProperty = CalculateIdProperty(type);

            if (idProperty == null)
            {
                throw new InvalidOperationException(String.Format(
                                                        "Unable to determine Id property for type `{0}`.", type.Name));
            }

            var props = type.GetProperties().OrderBy(p => p.Name);

            foreach (var prop in props)
            {
                if (prop == idProperty)
                {
                    continue;
                }

                var ignore = prop.CustomAttributes.Any(c => c.AttributeType == typeof(JsonIgnoreAttribute));
                if (ignore)
                {
                    continue;
                }

                var property = CreateResourceTypeField(prop);
                var jsonKey  = property.JsonKey;

                if (jsonKey == "id")
                {
                    throw new InvalidOperationException(
                              String.Format(
                                  "Failed to register type `{0}` because it contains a non-id property that would serialize as \"id\".",
                                  type.Name));
                }

                if (jsonKey == "type")
                {
                    throw new InvalidOperationException(
                              String.Format(
                                  "Failed to register type `{0}` because it contains a property that would serialize as \"type\".",
                                  type.Name));
                }

                if (fieldMap.ContainsKey(jsonKey))
                {
                    throw new InvalidOperationException(
                              String.Format(
                                  "Failed to register type `{0}` because contains multiple properties that would serialize as `{1}`.",
                                  type.Name, jsonKey));
                }

                fieldMap[jsonKey] = property;
            }

            if (filterByIdFactory == null)
            {
                filterByIdFactory = (param, id) =>
                {
                    var    propertyExpr = Expression.Property(param, idProperty);
                    object obj          = id;
                    if (obj == null)
                    {
                        var t = propertyExpr.Type;
                        if (t.IsValueType)
                        {
                            obj = Activator.CreateInstance(t);
                        }
                    }
                    var idExpr = Expression.Constant(Convert.ChangeType(obj, propertyExpr.Type));
                    return(Expression.Equal(propertyExpr, idExpr));
                };
            }

            if (sortByIdFactory == null)
            {
                sortByIdFactory = param => Expression.Property(param, idProperty);
            }

            return(new ResourceTypeRegistration(type, idProperty, resourceTypeName, fieldMap, filterByIdFactory,
                                                sortByIdFactory));
        }