private object DeserializeList(Type type, BsonArray value) { var itemType = Reflection.GetListItemType(type); var enumerable = (IEnumerable)Reflection.CreateInstance(type); var list = enumerable as IList; if (list != null) { foreach (BsonValue item in value) { list.Add(Deserialize(itemType, item)); } } else { #if NET35 var addMethod = type.GetMethod("Add"); #else var addMethod = type.GetRuntimeMethod("Add", new Type[1] { itemType }); #endif foreach (BsonValue item in value) { addMethod.Invoke(enumerable, new[] { Deserialize(itemType, item) }); } } return(enumerable); }
private object DeserializeList(Type type, BsonArray value) { var itemType = type.GetGenericArguments().FirstOrDefault() ?? type.GetInterfaces().First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable <>)).GetGenericArguments().First(); var enumerable = (IEnumerable)Reflection.CreateInstance(type); var list = enumerable as IList; if (list != null) { foreach (BsonValue item in value) { list.Add(Deserialize(itemType, item)); } } else { var addMethod = type.GetMethod("Add"); foreach (BsonValue item in value) { addMethod.Invoke(enumerable, new[] { Deserialize(itemType, item) }); } } return(enumerable); }
private object DeserializeList(Type type, BsonArray value) { var itemType = Reflection.UnderlyingTypeOf(type); var enumerable = (IEnumerable)Reflection.CreateInstance(type); var list = enumerable as IList; if (list != null) { foreach (BsonValue item in value) { list.Add(Deserialize(itemType, item)); } } else { var addMethod = type.GetMethod("Add"); foreach (BsonValue item in value) { addMethod.Invoke(enumerable, new[] { Deserialize(itemType, item) }); } } return(enumerable); }
private object DeserializeList(Type type, BsonArray value) { var itemType = Reflection.UnderlyingTypeOf(type); var list = (IList)Reflection.CreateInstance(type); foreach (var item in value) { list.Add(this.Deserialize(itemType, item)); } return(list); }
private object DeserializeList(Type type, BsonArray value) { #if PCL || NETSTANDARD var typeInfo = type.GetTypeInfo(); var itemType = typeInfo.GenericTypeArguments.FirstOrDefault() ?? typeInfo.ImplementedInterfaces.First(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IEnumerable <>)).GetTypeInfo().GenericTypeArguments.First(); #else var itemType = type.GetGenericArguments().FirstOrDefault() ?? type.GetInterfaces().First(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IEnumerable <>)).GetGenericArguments().First(); #endif var enumerable = (IEnumerable)Reflection.CreateInstance(type); var list = enumerable as IList; if (list != null) { foreach (BsonValue item in value) { list.Add(Deserialize(itemType, item)); } } else { #if PCL || NETSTANDARD var addMethod = type.GetRuntimeMethod("Add", new Type[1] { itemType }); #else var addMethod = type.GetMethod("Add"); #endif foreach (BsonValue item in value) { addMethod.Invoke(enumerable, new[] { Deserialize(itemType, item) }); } } return(enumerable); }
private object DeserializeList(Type type, BsonArray value) { var itemType = Reflection.GetListItemType(type); var enumerable = (IEnumerable)Reflection.CreateInstance(type); if (enumerable is IList list) { foreach (BsonValue item in value) { list.Add(this.Deserialize(itemType, item)); } } else { var addMethod = type.GetMethod("Add"); foreach (BsonValue item in value) { addMethod.Invoke(enumerable, new[] { this.Deserialize(itemType, item) }); } } return(enumerable); }
/// <summary> /// Deserilize a BsonValue to .NET object based on type parameter /// </summary> public object Deserialize(Type type, BsonValue value) { // null value - null returns if (value.IsNull) { return(null); } // test if has a custom type implementation else if (_customDeserializer.TryGetValue(type, out Func <BsonValue, object> custom)) { return(custom(value)); } // if is nullable, get underlying type else if (Reflection.IsNullable(type)) { type = Reflection.UnderlyingTypeOf(type); } var typeInfo = type.GetTypeInfo(); // check if your type is already a BsonValue/BsonDocument/BsonArray if (type == typeof(BsonValue)) { return(value); } else if (type == typeof(BsonDocument)) { return(value.AsDocument); } else if (type == typeof(BsonArray)) { return(value.AsArray); } // raw values to native bson values else if (_bsonTypes.Contains(type)) { return(value.RawValue); } // simple ConvertTo to basic .NET types else if (_basicTypes.Contains(type)) { return(Convert.ChangeType(value.RawValue, type)); } // special cast to UInt64 to Int64 else if (type == typeof(UInt64)) { return(unchecked ((UInt64)value.AsInt64)); } // enum value is an int else if (typeInfo.IsEnum) { if (value.IsString) { return(Enum.Parse(type, value.AsString)); } if (value.IsNumber) { return(value.AsInt32); } } // if value is array, deserialize as array else if (value.IsArray) { // when array are from an object (like in Dictionary<string, object> { ["array"] = new string[] { "a", "b" } if (type == typeof(object)) { return(this.DeserializeArray(typeof(object), value.AsArray)); } if (type.IsArray) { return(this.DeserializeArray(type.GetElementType(), value.AsArray)); } else { return(this.DeserializeList(type, value.AsArray)); } } // if value is document, deserialize as document else if (value.IsDocument) { // if type is anonymous use special handler if (type.IsAnonymousType()) { return(this.DeserializeAnonymousType(type, value.AsDocument)); } var doc = value.AsDocument; // test if value is object and has _type if (doc.TryGetValue("_type", out var typeField) && typeField.IsString) { type = _typeNameBinder.GetType(typeField.AsString); if (type == null) { throw LiteException.InvalidTypedName(typeField.AsString); } } // when complex type has no definition (== typeof(object)) use Dictionary<string, object> to better set values else if (type == typeof(object)) { type = typeof(Dictionary <string, object>); } var entity = this.GetEntityMapper(type); // initialize CreateInstance if (entity.CreateInstance == null) { entity.CreateInstance = this.GetTypeCtor(entity) ?? ((BsonDocument v) => Reflection.CreateInstance(entity.ForType)); } var o = _typeInstantiator(type) ?? entity.CreateInstance(doc); if (o is IDictionary dict) { if (o.GetType().GetTypeInfo().IsGenericType) { var k = type.GetGenericArguments()[0]; var t = type.GetGenericArguments()[1]; this.DeserializeDictionary(k, t, dict, value.AsDocument); } else { this.DeserializeDictionary(typeof(object), typeof(object), dict, value.AsDocument); } } else { this.DeserializeObject(entity, o, doc); } return(o); } // in last case, return value as-is - can cause "cast error" // it's used for "public object MyInt { get; set; }" return(value.RawValue); }
internal object Deserialize(Type type, BsonValue value) { Func <BsonValue, object> custom; // null value - null returns if (value.IsNull) { return(null); } // if is nullable, get underlying type else if (Reflection.IsNullable(type)) { type = Reflection.UnderlyingTypeOf(type); } // check if your type is already a BsonValue/BsonDocument/BsonArray if (type == typeof(BsonValue)) { return(new BsonValue(value)); } else if (type == typeof(BsonDocument)) { return(value.AsDocument); } else if (type == typeof(BsonArray)) { return(value.AsArray); } // raw values to native bson values else if (_bsonTypes.Contains(type)) { return(value.RawValue); } // simple ConvertTo to basic .NET types else if (_basicTypes.Contains(type)) { return(Convert.ChangeType(value.RawValue, type)); } // enum value is a string else if (type.GetTypeInfo().IsEnum) { return(Enum.Parse(type, value.AsString)); } // test if has a custom type implementation else if (_customDeserializer.TryGetValue(type, out custom)) { return(custom(value)); } // if value is array, deserialize as array else if (value.IsArray) { if (type.IsArray) { return(this.DeserializeArray(type.GetElementType(), value.AsArray)); } else { return(this.DeserializeList(type, value.AsArray)); } } // if value is document, deserialize as document else if (value.IsDocument) { BsonValue typeField; var doc = value.AsDocument; // test if value is object and has _type if (doc.RawValue.TryGetValue("_type", out typeField)) { type = Type.GetType(typeField.AsString); if (type == null) { throw LiteException.InvalidTypedName(typeField.AsString); } } var o = Reflection.CreateInstance(type); if (o is IDictionary && type.GetTypeInfo().IsGenericType) { #if !NETFULL var k = type.GetTypeInfo().GenericTypeArguments[0]; var t = type.GetTypeInfo().GenericTypeArguments[1]; #else var k = type.GetGenericArguments()[0]; var t = type.GetGenericArguments()[1]; #endif this.DeserializeDictionary(k, t, (IDictionary)o, value.AsDocument); } else { this.DeserializeObject(type, o, doc); } return(o); } // in last case, return value as-is - can cause "cast error" // it's used for "public object MyInt { get; set; }" return(value.RawValue); }
private object Deserialize(Type type, BsonValue value) { if (value.IsNull) { return(null); } // if is nullable, get underlying type if (Reflection.IsNullable(type)) { type = Reflection.UnderlyingTypeOf(type); } // check if your type is already a BsonValue if (type == typeof(BsonValue)) { return(new BsonValue(value)); } else if (type == typeof(BsonDocument)) { return(value.AsDocument); } else if (type == typeof(BsonArray)) { return(value.AsArray); } // bson types convert else if (_bsonTypes.Contains(type)) { return(value.RawValue); } else if (_basicTypes.Contains(type)) { return(Convert.ChangeType(value.RawValue, type)); } else if (type.IsEnum) { return(Enum.Parse(type, value.AsString)); } else if (type.IsArray) { return(this.DeserializeArray(type.GetElementType(), value.AsArray)); } // test if has a custom type implementation Func <BsonValue, object> custom; if (_customDeserializer.TryGetValue(type, out custom)) { return(custom(value)); } // create instance for object type var o = Reflection.CreateInstance(type); // check if type is a IList if (o is IList && type.IsGenericType) { this.DeserializeList(Reflection.UnderlyingTypeOf(type), (IList)o, value.AsArray); } else if (o is IDictionary && type.IsGenericType) { var k = type.GetGenericArguments()[0]; var t = type.GetGenericArguments()[1]; this.DeserializeDictionary(k, t, (IDictionary)o, value.AsDocument); } else { // otherwise is plain object this.DeserializeObject(type, o, value.AsDocument); } return(o); }