private void DeserializeDictionary(Type K, Type T, IDictionary dict, BsonDocument value) { foreach (var key in value.Keys) { var k = TypeInfoExtensions.GetTypeInfo(K).IsEnum ? Enum.Parse(K, key) : Convert.ChangeType(key, K); var v = Deserialize(T, value[key]); dict.Add(k, v); } }
public static bool IsNullable(Type type) { if (!TypeInfoExtensions.GetTypeInfo(type).IsGenericType) { return(false); } var g = type.GetGenericTypeDefinition(); return(g.Equals(typeof(Nullable <>))); }
/// <summary> /// Get underlying get - using to get inner Type from Nullable type /// </summary> public static Type UnderlyingTypeOf(Type type) { // works only for generics (if type is not generic, returns same type) var t = TypeInfoExtensions.GetTypeInfo(type); if (!TypeInfoExtensions.GetTypeInfo(type).IsGenericType) { return(type); } return(TypeInfoExtensions.GetTypeInfo(type).GetGenericArguments()[0]); }
private BsonValue VisitValue(Expression expr, Expression left) { // check if left side is an enum and convert to string before return Func <Type, object, BsonValue> convert = (type, value) => { var enumType = (left as UnaryExpression) == null ? null : (left as UnaryExpression).Operand.Type; if (enumType != null && TypeInfoExtensions.GetTypeInfo(enumType).IsEnum) { var str = Enum.GetName(enumType, value); return(_mapper.Serialize(typeof(string), str, 0)); } return(_mapper.Serialize(type, value, 0)); }; // its a constant; Eg: "fixed string" if (expr is ConstantExpression) { var value = (expr as ConstantExpression); return(convert(value.Type, value.Value)); } else if (expr is MemberExpression && _parameters.Count > 0) { var mExpr = (MemberExpression)expr; var mValue = VisitValue(mExpr.Expression, left); var value = mValue.AsDocument[mExpr.Member.Name]; return(convert(typeof(object), value)); } else if (expr is ParameterExpression) { BsonValue result; if (_parameters.TryGetValue((ParameterExpression)expr, out result)) { return(result); } } // execute expression var objectMember = Expression.Convert(expr, typeof(object)); var getterLambda = Expression.Lambda <Func <object> >(objectMember); var getter = getterLambda.Compile(); return(convert(typeof(object), getter())); }
private static void RegisterCommands() { lock (_commands) { var type = typeof(ICommand); var types = TypeInfoExtensions.GetTypeInfo(typeof(LiteEngine)).Assembly .GetTypes() .Where(p => type.IsAssignableFrom(p) && TypeInfoExtensions.GetTypeInfo(p).IsClass); _commands.Clear(); foreach (var cmd in types) { _commands.Add(Activator.CreateInstance(cmd) as ICommand); } } }
/// <summary> /// Get item type from a generic List or Array /// </summary> public static Type GetListItemType(Type listType) { if (listType.IsArray) { return(listType.GetElementType()); } foreach (var i in listType.GetInterfaces()) { if (TypeInfoExtensions.GetTypeInfo(i).IsGenericType&& i.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { return(TypeInfoExtensions.GetTypeInfo(i).GetGenericArguments()[0]); } // if interface is IEnumerable (non-generic), let's get from listType and not from interface // from #395 else if (TypeInfoExtensions.GetTypeInfo(listType).IsGenericType&& i == typeof(IEnumerable)) { return(TypeInfoExtensions.GetTypeInfo(listType).GetGenericArguments()[0]); } } return(typeof(object)); }
/// <summary> /// Returns true if Type is any kind of Array/IList/ICollection/.... /// </summary> public static bool IsList(Type type) { if (type.IsArray) { return(true); } if (type == typeof(string)) { return(false); // do not define "String" as IEnumerable<char> } foreach (var @interface in type.GetInterfaces()) { if (TypeInfoExtensions.GetTypeInfo(@interface).IsGenericType) { if (@interface.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { // if needed, you can also return the type used as generic argument return(true); } } } return(false); }
private BsonDocument SerializeObject(Type type, object obj, int depth) { var o = new BsonDocument(); var t = obj.GetType(); var entity = GetEntityMapper(t); var dict = o.RawValue; // adding _type only where property Type is not same as object instance type if (type != t) { dict["_type"] = new BsonValue(t.FullName + ", " + TypeInfoExtensions.GetTypeInfo(t).Assembly.GetName().Name); } foreach (var member in entity.Members.Where(x => x.Getter != null)) { // get member value var value = member.Getter(obj); if (value == null && SerializeNullValues == false && member.FieldName != "_id") { continue; } // if member has a custom serialization, use it if (member.Serialize != null) { dict[member.FieldName] = member.Serialize(value, this); } else { dict[member.FieldName] = Serialize(member.DataType, value, depth); } } return(o); }
/// <summary> /// Create a new instance from a Type /// </summary> public static object CreateInstance(Type type) { try { if (_cacheCtor.TryGetValue(type, out var c)) { return(c()); } } catch (Exception ex) { throw LiteException.InvalidCtor(type, ex); } lock (_cacheCtor) { try { if (_cacheCtor.TryGetValue(type, out var c)) { return(c()); } if (TypeInfoExtensions.GetTypeInfo(type).IsClass) { _cacheCtor.Add(type, c = CreateClass(type)); } else if (TypeInfoExtensions.GetTypeInfo(type).IsInterface) // some know interfaces { if (TypeInfoExtensions.GetTypeInfo(type).IsGenericType) { var typeDef = type.GetGenericTypeDefinition(); if (typeDef == typeof(IList <>) || typeDef == typeof(ICollection <>) || typeDef == typeof(IEnumerable <>)) { return(CreateInstance(GetGenericListOfType(UnderlyingTypeOf(type)))); } else if (typeDef == typeof(IDictionary <,>)) { var k = TypeInfoExtensions.GetTypeInfo(type).GetGenericArguments()[0]; var v = TypeInfoExtensions.GetTypeInfo(type).GetGenericArguments()[1]; return(CreateInstance(GetGenericDictionaryOfType(k, v))); } } throw LiteException.InvalidCtor(type, null); } else // structs { _cacheCtor.Add(type, c = CreateStruct(type)); } return(c()); } catch (Exception ex) { throw LiteException.InvalidCtor(type, ex); } } }
internal BsonValue Serialize(Type type, object obj, int depth) { if (++depth > MAX_DEPTH) { throw LiteException.DocumentMaxDepth(MAX_DEPTH, type); } if (obj == null) { return(BsonValue.Null); } Func <object, BsonValue> custom; // if is already a bson value if (obj is BsonValue) { return(new BsonValue((BsonValue)obj)); } // test string - mapper has some special options else if (obj is String) { var str = TrimWhitespace ? (obj as String).Trim() : (String)obj; if (EmptyStringToNull && str.Length == 0) { return(BsonValue.Null); } else { return(new BsonValue(str)); } } // basic Bson data types (cast datatype for better performance optimization) else if (obj is Int32) { return(new BsonValue((Int32)obj)); } else if (obj is Int64) { return(new BsonValue((Int64)obj)); } else if (obj is Double) { return(new BsonValue((Double)obj)); } else if (obj is Decimal) { return(new BsonValue((Decimal)obj)); } else if (obj is Byte[]) { return(new BsonValue((Byte[])obj)); } else if (obj is ObjectId) { return(new BsonValue((ObjectId)obj)); } else if (obj is Guid) { return(new BsonValue((Guid)obj)); } else if (obj is Boolean) { return(new BsonValue((Boolean)obj)); } else if (obj is DateTime) { return(new BsonValue((DateTime)obj)); } // basic .net type to convert to bson else if (obj is Int16 || obj is UInt16 || obj is Byte || obj is SByte) { return(new BsonValue(Convert.ToInt32(obj))); } else if (obj is UInt32) { return(new BsonValue(Convert.ToInt64(obj))); } else if (obj is UInt64) { var ulng = ((UInt64)obj); var lng = unchecked ((Int64)ulng); return(new BsonValue(lng)); } else if (obj is Single) { return(new BsonValue(Convert.ToDouble(obj))); } else if (obj is Char || obj is Enum) { return(new BsonValue(obj.ToString())); } // check if is a custom type else if (_customSerializer.TryGetValue(type, out custom) || _customSerializer.TryGetValue(obj.GetType(), out custom)) { return(custom(obj)); } // for dictionary else if (obj is IDictionary) { // when you are converting Dictionary<string, object> if (type == typeof(object)) { type = obj.GetType(); } var itemType = TypeInfoExtensions.GetTypeInfo(type).GetGenericArguments()[1]; return(SerializeDictionary(itemType, obj as IDictionary, depth)); } // check if is a list or array else if (obj is IEnumerable) { return(SerializeArray(Reflection.GetListItemType(obj.GetType()), obj as IEnumerable, depth)); } // otherwise serialize as a plain object else { return(SerializeObject(type, obj, depth)); } }
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)); } // special cast to UInt64 to Int64 else if (type == typeof(UInt64)) { return(unchecked ((UInt64)((Int64)value.RawValue))); } // enum value is an int else if (TypeInfoExtensions.GetTypeInfo(type).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) { // when array are from an object (like in Dictionary<string, object> { ["array"] = new string[] { "a", "b" } if (type == typeof(object)) { return(DeserializeArray(typeof(object), value.AsArray)); } if (type.IsArray) { return(DeserializeArray(type.GetElementType(), value.AsArray)); } else { return(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); } } // 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 o = _typeInstantiator(type); if (o is IDictionary && TypeInfoExtensions.GetTypeInfo(type).IsGenericType) { var k = TypeInfoExtensions.GetTypeInfo(type).GetGenericArguments()[0]; var t = TypeInfoExtensions.GetTypeInfo(type).GetGenericArguments()[1]; DeserializeDictionary(k, t, (IDictionary)o, value.AsDocument); } else { 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); }