예제 #1
0
        private ListJsonSerializer(Type type, bool encrypt, JsonMappings mappings)
        {
            _encrypt = encrypt;

            if (type.IsAssignableToGenericIEnumerable())
            {
                var itemType = type.GetGenericIEnumerableType().GetGenericArguments()[0];
                _itemSerializer = JsonSerializerFactory.GetSerializer(itemType, _encrypt, mappings);
            }
            else
            {
                _itemSerializer = JsonSerializerFactory.GetSerializer(typeof(object), _encrypt, mappings);
            }

            if (type.IsInterface)
            {
                if (type.IsGenericIEnumerable())
                {
                    var itemType = type.GetGenericArguments()[0];
                    type = typeof(List <>).MakeGenericType(itemType);
                }
                else
                {
                    type = typeof(List <object>);
                }
            }

            _createList = GetCreateListFunc(type);
            _addItem    = GetAddItemAction(type);
        }
        private DictionaryJsonSerializer(Type type, bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
        {
            _encrypt = encrypt;
            _mappings = mappings;
            _shouldUseAttributeDefinedInInterface = shouldUseAttributeDefinedInInterface;

            Type keyType;

            if (type.IsAssignableToGenericIDictionary())
            {
                var genericArguments = type.GetGenericArguments();
                keyType = genericArguments[0];

                if (typeof(IDictionary<string, object>).IsAssignableFrom(type))
                {
                    _valueSerializer = JsonSerializerFactory.GetSerializer(genericArguments[1], _encrypt, _mappings, shouldUseAttributeDefinedInInterface);
                    _write = GetIDictionaryOfStringToObjectWriteAction();
                }
                else if (type.IsAssignableToGenericIDictionaryOfStringToAnything())
                {
                    _valueSerializer = JsonSerializerFactory.GetSerializer(genericArguments[1], _encrypt, _mappings, shouldUseAttributeDefinedInInterface);
                    _write = GetIDictionaryOfStringToAnythingWriteAction();
                }
                else
                {
                    _keySerializer = JsonSerializerFactory.GetSerializer(genericArguments[0], _encrypt, _mappings, shouldUseAttributeDefinedInInterface);
                    _valueSerializer = JsonSerializerFactory.GetSerializer(genericArguments[1], _encrypt, _mappings, shouldUseAttributeDefinedInInterface);
                    _write = GetIDictionaryOfAnythingToAnythingWriteAction();
                }
            }
            else
            {
                keyType = typeof(object);

                _keySerializer = JsonSerializerFactory.GetSerializer(typeof(object), _encrypt, _mappings, shouldUseAttributeDefinedInInterface);
                _valueSerializer = _keySerializer;
                _write = GetIDictionaryOfAnythingToAnythingWriteAction();
            }

            if (type.IsInterface)
            {
                if (type.IsGenericIDictionary())
                {
                    type = typeof(Dictionary<,>).MakeGenericType(
                        type.GetGenericArguments()[0], type.GetGenericArguments()[1]);
                }
                else if (type == typeof(IDictionary))
                {
                    type = typeof(Dictionary<object, object>);
                }
                else
                {
                    throw new NotSupportedException(type.FullName);
                }
            }

            _createDictionary = GetCreateDictionaryFunc(type);
            _deserializeKey = GetDeserializeKeyFunc(keyType);
            _addToDictionary = GetAddToDictionaryAction(type);
        }
예제 #3
0
        private ListJsonSerializer(Type type, bool encrypt, JsonMappings mappings)
        {
            _encrypt = encrypt;

            if (type.IsAssignableToGenericIEnumerable())
            {
                var itemType = type.GetGenericIEnumerableType().GetGenericArguments()[0];
                _itemSerializer = JsonSerializerFactory.GetSerializer(itemType, _encrypt, mappings);
            }
            else
            {
                _itemSerializer = JsonSerializerFactory.GetSerializer(typeof(object), _encrypt, mappings);
            }

            if (type.IsInterface)
            {
                if (type.IsGenericIEnumerable())
                {
                    var itemType = type.GetGenericArguments()[0];
                    type = typeof(List<>).MakeGenericType(itemType);
                }
                else
                {
                    type = typeof(List<object>);
                }
            }

            _createList = GetCreateListFunc(type);
            _addItem = GetAddItemAction(type);
        }
        private CustomJsonSerializer(Type type, bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
        {
            _mappings = mappings;
            _shouldUseAttributeDefinedInInterface = shouldUseAttributeDefinedInInterface;
            _type = type;

            if (_mappings.MappingsByType.ContainsKey(type))
            {
                _type = _mappings.MappingsByType[type];
            }
            else
            {
                var mappingAttribute = _type.GetCustomAttribute<JsonMappingAttribute>();
                if (mappingAttribute != null)
                {
                    _type = mappingAttribute.Type;
                }
            }

            _encrypt = encrypt || type.GetCustomAttribute<EncryptAttribute>() != null;

            var serializableProperties = GetSerializableProperties(_type);
            _deserializingPropertiesMap = serializableProperties.ToDictionary(p => p.Name);

            if (!_type.IsAbstract)
            {
                _serializingPropertiesMap[_type] = serializableProperties;
            }

            _createObjectFactory = new Lazy<Func<IObjectFactory>>(GetCreateObjectFactoryFunc);
        }
예제 #5
0
        private DictionaryJsonSerializer(Type type, bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
        {
            _encrypt  = encrypt;
            _mappings = mappings;
            _shouldUseAttributeDefinedInInterface = shouldUseAttributeDefinedInInterface;

            Type keyType;

            if (type.IsAssignableToGenericIDictionary())
            {
                var genericArguments = type.GetGenericArguments();
                keyType = genericArguments[0];

                if (typeof(IDictionary <string, object>).IsAssignableFrom(type))
                {
                    _valueSerializer = JsonSerializerFactory.GetSerializer(genericArguments[1], _encrypt, _mappings, shouldUseAttributeDefinedInInterface);
                    _write           = GetIDictionaryOfStringToObjectWriteAction();
                }
                else if (type.IsAssignableToGenericIDictionaryOfStringToAnything())
                {
                    _valueSerializer = JsonSerializerFactory.GetSerializer(genericArguments[1], _encrypt, _mappings, shouldUseAttributeDefinedInInterface);
                    _write           = GetIDictionaryOfStringToAnythingWriteAction();
                }
                else
                {
                    _keySerializer   = JsonSerializerFactory.GetSerializer(genericArguments[0], _encrypt, _mappings, shouldUseAttributeDefinedInInterface);
                    _valueSerializer = JsonSerializerFactory.GetSerializer(genericArguments[1], _encrypt, _mappings, shouldUseAttributeDefinedInInterface);
                    _write           = GetIDictionaryOfAnythingToAnythingWriteAction();
                }
            }
            else
            {
                keyType = typeof(object);

                _keySerializer   = JsonSerializerFactory.GetSerializer(typeof(object), _encrypt, _mappings, shouldUseAttributeDefinedInInterface);
                _valueSerializer = _keySerializer;
                _write           = GetIDictionaryOfAnythingToAnythingWriteAction();
            }

            if (type.IsInterface)
            {
                if (type.IsGenericIDictionary())
                {
                    type = typeof(Dictionary <,>).MakeGenericType(
                        type.GetGenericArguments()[0], type.GetGenericArguments()[1]);
                }
                else if (type == typeof(IDictionary))
                {
                    type = typeof(Dictionary <object, object>);
                }
                else
                {
                    throw new NotSupportedException(type.FullName);
                }
            }

            _createDictionary = GetCreateDictionaryFunc(type);
            _deserializeKey   = GetDeserializeKeyFunc(keyType);
            _addToDictionary  = GetAddToDictionaryAction(type);
        }
예제 #6
0
        private CustomJsonSerializer(Type type, bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
        {
            _mappings = mappings;
            _shouldUseAttributeDefinedInInterface = shouldUseAttributeDefinedInInterface;
            _type = type;

            if (_mappings.MappingsByType.ContainsKey(type))
            {
                _type = _mappings.MappingsByType[type];
            }
            else
            {
                var mappingAttribute = _type.GetCustomAttribute <JsonMappingAttribute>();
                if (mappingAttribute != null)
                {
                    _type = mappingAttribute.Type;
                }
            }

            _encrypt = encrypt || type.GetCustomAttribute <EncryptAttribute>() != null;

            var serializableProperties = GetSerializableProperties(_type);

            _deserializingPropertiesMap = serializableProperties.ToDictionary(p => p.Name);

            if (!_type.IsAbstract)
            {
                _serializingPropertiesMap[_type] = serializableProperties;
            }

            _createObjectFactory = new Lazy <Func <IObjectFactory> >(GetCreateObjectFactoryFunc);
        }
        private DynamicJsonSerializer(bool encrypt, JsonMappings mappings)
        {
            _jsonObjectSerializer = new JsonObjectSerializer(this);
            _jsonArraySerializer = new JsonArraySerializer(this);

            _encrypt = encrypt;
            _mappings = mappings;
        }
예제 #8
0
        private DynamicJsonSerializer(bool encrypt, JsonMappings mappings)
        {
            _jsonObjectSerializer = new JsonObjectSerializer(this);
            _jsonArraySerializer  = new JsonArraySerializer(this);

            _encrypt  = encrypt;
            _mappings = mappings;
        }
        private DynamicJsonSerializer(bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
        {
            _jsonObjectSerializer = new JsonObjectSerializer(this);
            _jsonArraySerializer = new JsonArraySerializer(this);

            _encrypt = encrypt;
            _mappings = mappings;
            _shouldUseAttributeDefinedInInterface = shouldUseAttributeDefinedInInterface;
        }
        private DynamicJsonSerializer(bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
        {
            _jsonObjectSerializer = new JsonObjectSerializer(this);
            _jsonArraySerializer  = new JsonArraySerializer(this);

            _encrypt  = encrypt;
            _mappings = mappings;
            _shouldUseAttributeDefinedInInterface = shouldUseAttributeDefinedInInterface;
        }
예제 #11
0
        public static IJsonSerializerInternal GetSerializer(
            Type type,
            bool encrypt,
            JsonMappings mappings,
            bool shouldUseAttributeDefinedInInterface)
        {
            return(_cache.GetOrAdd(
                       Tuple.Create(type, encrypt, mappings),
                       tuple =>
            {
                if (type == typeof(object))
                {
                    return DynamicJsonSerializer.Get(encrypt, mappings, shouldUseAttributeDefinedInInterface);
                }

                if (type.IsJsonStringType())
                {
                    return StringJsonSerializer.Get(type, encrypt);
                }

                if (type.IsJsonNumericType())
                {
                    return NumberJsonSerializer.Get(type, encrypt);
                }

                if (type.IsJsonBooleanType())
                {
                    return BooleanJsonSerializer.Get(encrypt, type == typeof(bool?));
                }

                if (type.IsAssignableToGenericIDictionary() ||
                    typeof(IDictionary).IsAssignableFrom(type))
                {
                    return DictionaryJsonSerializer.Get(type, encrypt, mappings, shouldUseAttributeDefinedInInterface);
                }

                if (typeof(IEnumerable).IsAssignableFrom(type))
                {
                    return ListJsonSerializer.Get(type, encrypt, mappings, shouldUseAttributeDefinedInInterface);
                }

                // TODO: Handle more types or possibly black-list some types or types of types.

                return CustomJsonSerializer.Get(type, encrypt, mappings, shouldUseAttributeDefinedInInterface);
            }));
        }
        public static IJsonSerializerInternal GetSerializer(
            Type type,
            bool encrypt,
            JsonMappings mappings,
            bool shouldUseAttributeDefinedInInterface)
        {
            return _cache.GetOrAdd(
                Tuple.Create(type, encrypt, mappings),
                tuple =>
                {
                    if (type == typeof(object))
                    {
                        return DynamicJsonSerializer.Get(encrypt, mappings, shouldUseAttributeDefinedInInterface);
                    }

                    if (type.IsJsonStringType())
                    {
                        return StringJsonSerializer.Get(type, encrypt);
                    }

                    if (type.IsJsonNumericType())
                    {
                        return NumberJsonSerializer.Get(type, encrypt);
                    }

                    if (type.IsJsonBooleanType())
                    {
                        return BooleanJsonSerializer.Get(encrypt, type == typeof(bool?));
                    }

                    if (type.IsAssignableToGenericIDictionary()
                        || typeof(IDictionary).IsAssignableFrom(type))
                    {
                        return DictionaryJsonSerializer.Get(type, encrypt, mappings, shouldUseAttributeDefinedInInterface);
                    }

                    if (typeof(IEnumerable).IsAssignableFrom(type))
                    {
                        return ListJsonSerializer.Get(type, encrypt, mappings, shouldUseAttributeDefinedInInterface);
                    }

                    // TODO: Handle more types or possibly black-list some types or types of types.

                    return CustomJsonSerializer.Get(type, encrypt, mappings, shouldUseAttributeDefinedInInterface);
                });
        }
예제 #13
0
        private ListJsonSerializer(Type type, bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
        {
            _encrypt = encrypt;

            if (type.IsAssignableToGenericIEnumerable())
            {
                var itemType = type.GetGenericIEnumerableType().GetGenericArguments()[0];
                _itemSerializer = JsonSerializerFactory.GetSerializer(itemType, _encrypt, mappings, shouldUseAttributeDefinedInInterface);
            }
            else
            {
                _itemSerializer = JsonSerializerFactory.GetSerializer(typeof(object), _encrypt, mappings, shouldUseAttributeDefinedInInterface);
            }

            if (type.IsInterface)
            {
                if (type.IsGenericIEnumerable())
                {
                    var itemType = type.GetGenericArguments()[0];
                    type = typeof(List <>).MakeGenericType(itemType);
                }
                else
                {
                    type = typeof(List <object>);
                }
            }

            var listType = type;

            if (type.IsArray)
            {
                if (type.GetArrayRank() > 1)
                {
                    throw new NotSupportedException("Only arrays with a rank of one are supported: " + type + ".");
                }

                var itemType = type.GetElementType();
                listType = typeof(List <>).MakeGenericType(itemType);
            }

            _createList    = GetCreateListFunc(listType);
            _addItem       = GetAddItemAction(listType);
            _transformList = GetTransformListFunc(type, listType);
        }
예제 #14
0
        private ListJsonSerializer(Type type, bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
        {
            _encrypt = encrypt;

            if (type.IsAssignableToGenericIEnumerable())
            {
                var itemType = type.GetGenericIEnumerableType().GetGenericArguments()[0];
                _itemSerializer = JsonSerializerFactory.GetSerializer(itemType, _encrypt, mappings, shouldUseAttributeDefinedInInterface);
            }
            else
            {
                _itemSerializer = JsonSerializerFactory.GetSerializer(typeof(object), _encrypt, mappings, shouldUseAttributeDefinedInInterface);
            }

            if (type.IsInterface)
            {
                if (type.IsGenericIEnumerable())
                {
                    var itemType = type.GetGenericArguments()[0];
                    type = typeof(List<>).MakeGenericType(itemType);
                }
                else
                {
                    type = typeof(List<object>);
                }
            }

            var listType = type;

            if (type.IsArray)
            {
                if (type.GetArrayRank() > 1)
                {
                    throw new NotSupportedException("Only arrays with a rank of one are supported: " + type + ".");
                }

                var itemType = type.GetElementType();
                listType = typeof(List<>).MakeGenericType(itemType);
            }

            _createList = GetCreateListFunc(listType);
            _addItem = GetAddItemAction(listType);
            _transformList = GetTransformListFunc(type, listType);
        }
예제 #15
0
 public static DynamicJsonSerializer Get(bool encrypt, JsonMappings mappings)
 {
     return(_cache.GetOrAdd(Tuple.Create(encrypt, mappings), t => new DynamicJsonSerializer(t.Item1, t.Item2)));
 }
 public static DynamicJsonSerializer Get(bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface = false)
 {
     return _cache.GetOrAdd(Tuple.Create(encrypt, mappings, shouldUseAttributeDefinedInInterface), t => new DynamicJsonSerializer(t.Item1, t.Item2, t.Item3));
 }
예제 #17
0
 public static ListJsonSerializer Get(Type type, bool encrypt, JsonMappings mappings)
 {
     return(_cache.GetOrAdd(Tuple.Create(type, encrypt, mappings), t => new ListJsonSerializer(t.Item1, t.Item2, t.Item3)));
 }
예제 #18
0
 public static CustomJsonSerializer Get(Type type, bool encrypt, JsonMappings mappings)
 {
     return _cache.GetOrAdd(Tuple.Create(type, encrypt, mappings), t => new CustomJsonSerializer(t.Item1, t.Item2, t.Item3));
 }
예제 #19
0
 public static DynamicJsonSerializer Get(bool encrypt, JsonMappings mappings)
 {
     return _cache.GetOrAdd(Tuple.Create(encrypt, mappings), t => new DynamicJsonSerializer(t.Item1, t.Item2));
 }
예제 #20
0
        public static IJsonSerializerInternal GetSerializer(
            Type type,
            bool encrypt,
            JsonMappings mappings)
        {
            return _cache.GetOrAdd(
                Tuple.Create(type, encrypt, mappings),
                tuple =>
                {
                    if (type == typeof(object))
                    {
                        return DynamicJsonSerializer.Get(encrypt, mappings);
                    }

                    if (type == typeof(string)
                        || type == typeof(DateTime)
                        || type == typeof(DateTime?)
                        || type == typeof(DateTimeOffset)
                        || type == typeof(DateTimeOffset?)
                        || type == typeof(Guid)
                        || type == typeof(Guid?)
                        || type.IsEnum
                        || (type.IsNullableType() && Nullable.GetUnderlyingType(type).IsEnum)
                        || type == typeof(Type)
                        || type == typeof(Uri))
                    {
                        return StringJsonSerializer.Get(type, encrypt);
                    }

                    if (type == typeof(double)
                        || type == typeof(double?)
                        || type == typeof(int)
                        || type == typeof(int?)
                        || type == typeof(float)
                        || type == typeof(float?)
                        || type == typeof(long)
                        || type == typeof(long?)
                        || type == typeof(decimal)
                        || type == typeof(decimal?)
                        || type == typeof(byte)
                        || type == typeof(byte?)
                        || type == typeof(sbyte)
                        || type == typeof(sbyte?)
                        || type == typeof(short)
                        || type == typeof(short?)
                        || type == typeof(ushort)
                        || type == typeof(ushort?)
                        || type == typeof(uint)
                        || type == typeof(uint?)
                        || type == typeof(ulong)
                        || type == typeof(ulong?)) // TODO: handle more number types.
                    {
                        return NumberJsonSerializer.Get(type, encrypt);
                    }

                    if (type == typeof(bool)
                        || type == typeof(bool?))
                    {
                        return BooleanJsonSerializer.Get(encrypt, type == typeof(bool?));
                    }

                    if (type.IsAssignableToGenericIDictionary()
                        || typeof(IDictionary).IsAssignableFrom(type))
                    {
                        return DictionaryJsonSerializer.Get(type, encrypt, mappings);
                    }

                    if (typeof(IEnumerable).IsAssignableFrom(type))
                    {
                        return ListJsonSerializer.Get(type, encrypt, mappings);
                    }

                    // TODO: Handle more types or possibly black-list some types or types of types.

                    return CustomJsonSerializer.Get(type, encrypt, mappings);
                });
        }
 public static DynamicJsonSerializer Get(bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface = false)
 {
     return(_cache.GetOrAdd(Tuple.Create(encrypt, mappings, shouldUseAttributeDefinedInInterface), t => new DynamicJsonSerializer(t.Item1, t.Item2, t.Item3)));
 }
        public SerializableJsonProperty(PropertyInfo propertyInfo, bool encrypt, JsonMappings mappings)
        {
            if (propertyInfo.DeclaringType == null)
            {
                throw new ArgumentException("The DeclaringType of the PropertyInfo must not be null.", "propertyInfo");
            }

            _mappings = mappings;
            _name     = propertyInfo.GetName();

            var propertyType = propertyInfo.PropertyType;

            if (_mappings.MappingsByProperty.ContainsKey(propertyInfo))
            {
                propertyType = _mappings.MappingsByProperty[propertyInfo];
            }
            else if (_mappings.MappingsByType.ContainsKey(propertyType))
            {
                propertyType = _mappings.MappingsByType[propertyType];
            }
            else
            {
                var mappingAttribute = (JsonMappingAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(JsonMappingAttribute));
                if (mappingAttribute != null)
                {
                    propertyType = mappingAttribute.Type;
                }
            }

            _serializer = new Lazy <IJsonSerializerInternal>(() => JsonSerializerFactory.GetSerializer(propertyType, encrypt, _mappings));

            _getValue = GetGetValueFunc(propertyInfo, propertyInfo.DeclaringType);

            if (propertyInfo.IsReadWriteProperty())
            {
                _setValue = GetSetValueAction(propertyInfo, propertyInfo.DeclaringType);
            }
            else if (propertyInfo.IsJsonSerializableReadOnlyProperty())
            {
                // TODO: Before any of these checks, see if there is a constructor that matches this property. If so, don't do the "addable" deserialization technique.

                if (typeof(IDictionary).IsAssignableFrom(propertyType))
                {
                    _setValue = (instance, value) =>
                    {
                        var dictionary            = (IDictionary)value;
                        var destinationDictionary = (IDictionary)_getValue(instance);

                        foreach (DictionaryEntry item in dictionary)
                        {
                            destinationDictionary.Add(item.Key, item.Value);
                        }
                    };
                }
                else if (propertyType.IsAssignableToGenericIDictionary())
                {
                    var valueParameter = Expression.Parameter(typeof(object), "value");

                    var enumerableType = propertyType.GetGenericIEnumerableType();
                    var convertValue   = Expression.Convert(valueParameter, enumerableType);

                    var getEnumeratorMethod = enumerableType.GetMethod("GetEnumerator");
                    var callGetEnumerator   = Expression.Call(convertValue, getEnumeratorMethod);

                    var getEnumeratorLambda =
                        Expression.Lambda <Func <object, IEnumerator> >(callGetEnumerator, valueParameter);

                    var getEnumerator = getEnumeratorLambda.Compile();

                    var itemParameter = Expression.Parameter(typeof(object), "item");

                    var dictionaryType             = propertyType.GetGenericIDictionaryType();
                    var dictionaryGenericArguments = dictionaryType.GetGenericArguments();
                    var keyValuePairType           =
                        typeof(KeyValuePair <,>).MakeGenericType(
                            dictionaryGenericArguments[0], dictionaryGenericArguments[1]);

                    var convertItem = Expression.Convert(itemParameter, keyValuePairType);

                    var        keyPropertyInfo = keyValuePairType.GetProperty("Key");
                    Expression keyProperty     = Expression.Property(convertItem, keyPropertyInfo);

                    if (keyPropertyInfo.PropertyType.IsValueType) // Boxing is required
                    {
                        keyProperty = Expression.Convert(keyProperty, typeof(object));
                    }

                    var getItemKeyLambda = Expression.Lambda <Func <object, object> >(keyProperty, itemParameter);
                    var getItemKey       = getItemKeyLambda.Compile();

                    var        valuePropertyInfo = keyValuePairType.GetProperty("Value");
                    Expression valueProperty     = Expression.Property(convertItem, valuePropertyInfo);

                    if (valuePropertyInfo.PropertyType.IsValueType) // Boxing is required
                    {
                        valueProperty = Expression.Convert(valueProperty, typeof(object));
                    }

                    var getItemValueLambda = Expression.Lambda <Func <object, object> >(valueProperty, itemParameter);
                    var getItemValue       = getItemValueLambda.Compile();

                    var destinationDictionaryParameter = Expression.Parameter(typeof(object), "destinationDictionary");
                    var keyParameter = Expression.Parameter(typeof(object), "key");

                    var convertDestinationDictionary = Expression.Convert(destinationDictionaryParameter, dictionaryType);
                    var convertKey = Expression.Convert(keyParameter, keyPropertyInfo.PropertyType);
                    convertValue = Expression.Convert(valueParameter, valuePropertyInfo.PropertyType);

                    var addMethod     = dictionaryType.GetMethod("Add");
                    var callAddMethod = Expression.Call(
                        convertDestinationDictionary, addMethod, convertKey, convertValue);

                    var addLambda = Expression.Lambda <Action <object, object, object> >(
                        callAddMethod, destinationDictionaryParameter, keyParameter, valueParameter);
                    var add = addLambda.Compile();

                    _setValue = (instance, value) =>
                    {
                        var dictionaryEnumerator  = getEnumerator(value);
                        var destinationDictionary = _getValue(instance);

                        while (dictionaryEnumerator.MoveNext())
                        {
                            add(destinationDictionary, getItemKey(dictionaryEnumerator.Current), getItemValue(dictionaryEnumerator.Current));
                        }
                    };
                }
                else if (!propertyType.IsArray)
                {
                    if (typeof(IList).IsAssignableFrom(propertyType))
                    {
                        _setValue = (instance, value) =>
                        {
                            var list            = (IList)value;
                            var destinationList = (IList)_getValue(instance);

                            foreach (var item in list)
                            {
                                destinationList.Add(item);
                            }
                        };
                    }
                    else if (propertyType.IsAssignableToGenericICollection())
                    {
                        var destinationListParameter = Expression.Parameter(typeof(object), "destinationList");
                        var itemParameter            = Expression.Parameter(typeof(object), "item");

                        var collectionType = propertyType.GetGenericICollectionType();

                        var itemType             = collectionType.GetGenericArguments()[0];
                        var convertItemParameter = Expression.Convert(itemParameter, itemType);

                        var convertDestinationList = Expression.Convert(destinationListParameter, collectionType);

                        var addMethod     = collectionType.GetMethod("Add");
                        var callAddMethod = Expression.Call(
                            convertDestinationList,
                            addMethod,
                            new Expression[] { convertItemParameter });

                        var lambda = Expression.Lambda <Action <object, object> >(
                            callAddMethod,
                            destinationListParameter,
                            itemParameter);
                        var add = lambda.Compile();

                        _setValue = (instance, value) =>
                        {
                            var destinationList = _getValue(instance);

                            foreach (var item in (IEnumerable)value)
                            {
                                add(destinationList, item);
                            }
                        };
                    }
                }
            }
        }
예제 #23
0
 public static DictionaryJsonSerializer Get(Type type, bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
 {
     return(_cache.GetOrAdd(Tuple.Create(type, encrypt, mappings, shouldUseAttributeDefinedInInterface), t => new DictionaryJsonSerializer(t.Item1, t.Item2, t.Item3, t.Item4)));
 }
        public SerializableJsonProperty(PropertyInfo propertyInfo, bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
        {
            if (propertyInfo.DeclaringType == null)
            {
                throw new ArgumentException("The DeclaringType of the PropertyInfo must not be null.", "propertyInfo");
            }

            _mappings = mappings;
            _name = propertyInfo.GetName(shouldUseAttributeDefinedInInterface);

            var propertyType = propertyInfo.PropertyType;

            if (_mappings.MappingsByProperty.ContainsKey(propertyInfo))
            {
                propertyType = _mappings.MappingsByProperty[propertyInfo];
            }
            else if (_mappings.MappingsByType.ContainsKey(propertyType))
            {
                propertyType = _mappings.MappingsByType[propertyType];
            }
            else
            {
                var mappingAttribute = propertyInfo.GetCustomAttribute<JsonMappingAttribute>(shouldUseAttributeDefinedInInterface);
                if (mappingAttribute != null)
                {
                    propertyType = mappingAttribute.Type;
                }
            }

            _serializer = new Lazy<IJsonSerializerInternal>(() => JsonSerializerFactory.GetSerializer(propertyType, encrypt, _mappings, shouldUseAttributeDefinedInInterface));

            _getValue = GetGetValueFunc(propertyInfo, propertyInfo.DeclaringType);

            if (propertyInfo.IsReadWriteProperty())
            {
                _setValue = GetSetValueAction(propertyInfo, propertyInfo.DeclaringType);
            }
            else if (propertyInfo.IsJsonSerializableReadOnlyProperty())
            {
                // TODO: Before any of these checks, see if there is a constructor that matches this property. If so, don't do the "addable" deserialization technique.

                if (typeof(IDictionary).IsAssignableFrom(propertyType))
                {
                    _setValue = (instance, value) =>
                    {
                        var dictionary = (IDictionary)value;
                        var destinationDictionary = (IDictionary)_getValue(instance);

                        foreach (DictionaryEntry item in dictionary)
                        {
                            destinationDictionary.Add(item.Key, item.Value);
                        }
                    };
                }
                else if (propertyType.IsAssignableToGenericIDictionary())
                {
                    var valueParameter = Expression.Parameter(typeof(object), "value");

                    var enumerableType = propertyType.GetGenericIEnumerableType();
                    var convertValue = Expression.Convert(valueParameter, enumerableType);

                    var getEnumeratorMethod = enumerableType.GetMethod("GetEnumerator");
                    var callGetEnumerator = Expression.Call(convertValue, getEnumeratorMethod);

                    var getEnumeratorLambda =
                        Expression.Lambda<Func<object, IEnumerator>>(callGetEnumerator, valueParameter);

                    var getEnumerator = getEnumeratorLambda.Compile();

                    var itemParameter = Expression.Parameter(typeof(object), "item");

                    var dictionaryType = propertyType.GetGenericIDictionaryType();
                    var dictionaryGenericArguments = dictionaryType.GetGenericArguments();
                    var keyValuePairType =
                        typeof(KeyValuePair<,>).MakeGenericType(
                            dictionaryGenericArguments[0], dictionaryGenericArguments[1]);

                    var convertItem = Expression.Convert(itemParameter, keyValuePairType);

                    var keyPropertyInfo = keyValuePairType.GetProperty("Key");
                    Expression keyProperty = Expression.Property(convertItem, keyPropertyInfo);

                    if (keyPropertyInfo.PropertyType.IsValueType) // Boxing is required
                    {
                        keyProperty = Expression.Convert(keyProperty, typeof(object));
                    }

                    var getItemKeyLambda = Expression.Lambda<Func<object, object>>(keyProperty, itemParameter);
                    var getItemKey = getItemKeyLambda.Compile();

                    var valuePropertyInfo = keyValuePairType.GetProperty("Value");
                    Expression valueProperty = Expression.Property(convertItem, valuePropertyInfo);

                    if (valuePropertyInfo.PropertyType.IsValueType) // Boxing is required
                    {
                        valueProperty = Expression.Convert(valueProperty, typeof(object));
                    }

                    var getItemValueLambda = Expression.Lambda<Func<object, object>>(valueProperty, itemParameter);
                    var getItemValue = getItemValueLambda.Compile();

                    var destinationDictionaryParameter = Expression.Parameter(typeof(object), "destinationDictionary");
                    var keyParameter = Expression.Parameter(typeof(object), "key");

                    var convertDestinationDictionary = Expression.Convert(destinationDictionaryParameter, dictionaryType);
                    var convertKey = Expression.Convert(keyParameter, keyPropertyInfo.PropertyType);
                    convertValue = Expression.Convert(valueParameter, valuePropertyInfo.PropertyType);

                    var addMethod = dictionaryType.GetMethod("Add");
                    var callAddMethod = Expression.Call(
                        convertDestinationDictionary, addMethod, convertKey, convertValue);

                    var addLambda = Expression.Lambda<Action<object, object, object>>(
                        callAddMethod, destinationDictionaryParameter, keyParameter, valueParameter);
                    var add = addLambda.Compile();

                    _setValue = (instance, value) =>
                    {
                        var dictionaryEnumerator = getEnumerator(value);
                        var destinationDictionary = _getValue(instance);

                        while (dictionaryEnumerator.MoveNext())
                        {
                            add(destinationDictionary, getItemKey(dictionaryEnumerator.Current), getItemValue(dictionaryEnumerator.Current));
                        }
                    };
                }
                else if (!propertyType.IsArray)
                {
                    if (typeof(IList).IsAssignableFrom(propertyType))
                    {
                        _setValue = (instance, value) =>
                        {
                            var list = (IList)value;
                            var destinationList = (IList)_getValue(instance);

                            foreach (var item in list)
                            {
                                destinationList.Add(item);
                            }
                        };
                    }
                    else if (propertyType.IsAssignableToGenericICollection())
                    {
                        var destinationListParameter = Expression.Parameter(typeof(object), "destinationList");
                        var itemParameter = Expression.Parameter(typeof(object), "item");

                        var collectionType = propertyType.GetGenericICollectionType();

                        var itemType = collectionType.GetGenericArguments()[0];
                        var convertItemParameter = Expression.Convert(itemParameter, itemType);

                        var convertDestinationList = Expression.Convert(destinationListParameter, collectionType);

                        var addMethod = collectionType.GetMethod("Add");
                        var callAddMethod = Expression.Call(
                            convertDestinationList,
                            addMethod,
                            new Expression[] { convertItemParameter });

                        var lambda = Expression.Lambda<Action<object, object>>(
                            callAddMethod,
                            destinationListParameter,
                            itemParameter);
                        var add = lambda.Compile();

                        _setValue = (instance, value) =>
                        {
                            var destinationList = _getValue(instance);

                            foreach (var item in (IEnumerable)value)
                            {
                                add(destinationList, item);
                            }
                        };
                    }
                }
            }
            else
            {
                _setValue = (instance, value) => {};
            }
        }
예제 #25
0
 public static ListJsonSerializer Get(Type type, bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface)
 {
     return _cache.GetOrAdd(Tuple.Create(type, encrypt, mappings, shouldUseAttributeDefinedInInterface), t => new ListJsonSerializer(t.Item1, t.Item2, t.Item3, t.Item4));
 }
예제 #26
0
        public static IJsonSerializerInternal GetSerializer(
            Type type,
            bool encrypt,
            JsonMappings mappings)
        {
            return(_cache.GetOrAdd(
                       Tuple.Create(type, encrypt, mappings),
                       tuple =>
            {
                if (type == typeof(object))
                {
                    return DynamicJsonSerializer.Get(encrypt, mappings);
                }

                if (type == typeof(string) ||
                    type == typeof(DateTime) ||
                    type == typeof(DateTime?) ||
                    type == typeof(DateTimeOffset) ||
                    type == typeof(DateTimeOffset?) ||
                    type == typeof(Guid) ||
                    type == typeof(Guid?) ||
                    type.IsEnum ||
                    (type.IsNullableType() && Nullable.GetUnderlyingType(type).IsEnum) ||
                    type == typeof(Type) ||
                    type == typeof(Uri))
                {
                    return StringJsonSerializer.Get(type, encrypt);
                }

                if (type == typeof(double) ||
                    type == typeof(double?) ||
                    type == typeof(int) ||
                    type == typeof(int?) ||
                    type == typeof(float) ||
                    type == typeof(float?) ||
                    type == typeof(long) ||
                    type == typeof(long?) ||
                    type == typeof(decimal) ||
                    type == typeof(decimal?) ||
                    type == typeof(byte) ||
                    type == typeof(byte?) ||
                    type == typeof(sbyte) ||
                    type == typeof(sbyte?) ||
                    type == typeof(short) ||
                    type == typeof(short?) ||
                    type == typeof(ushort) ||
                    type == typeof(ushort?) ||
                    type == typeof(uint) ||
                    type == typeof(uint?) ||
                    type == typeof(ulong) ||
                    type == typeof(ulong?))        // TODO: handle more number types.
                {
                    return NumberJsonSerializer.Get(type, encrypt);
                }

                if (type == typeof(bool) ||
                    type == typeof(bool?))
                {
                    return BooleanJsonSerializer.Get(encrypt, type == typeof(bool?));
                }

                if (type.IsAssignableToGenericIDictionary() ||
                    typeof(IDictionary).IsAssignableFrom(type))
                {
                    return DictionaryJsonSerializer.Get(type, encrypt, mappings);
                }

                if (typeof(IEnumerable).IsAssignableFrom(type))
                {
                    return ListJsonSerializer.Get(type, encrypt, mappings);
                }

                // TODO: Handle more types or possibly black-list some types or types of types.

                return CustomJsonSerializer.Get(type, encrypt, mappings);
            }));
        }