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); }
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); }
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); }
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; }
private DynamicJsonSerializer(bool encrypt, JsonMappings mappings, bool shouldUseAttributeDefinedInInterface) { _jsonObjectSerializer = new JsonObjectSerializer(this); _jsonArraySerializer = new JsonArraySerializer(this); _encrypt = encrypt; _mappings = mappings; _shouldUseAttributeDefinedInInterface = 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); })); }
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); }); }
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); }
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); }
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)); }
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))); }
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)); }
public static DynamicJsonSerializer Get(bool encrypt, JsonMappings mappings) { return _cache.GetOrAdd(Tuple.Create(encrypt, mappings), t => new DynamicJsonSerializer(t.Item1, t.Item2)); }
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); } }; } } } }
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) => {}; } }
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)); }
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); })); }