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);
            }
        }
Exemple #2
0
        public static bool IsNullable(Type type)
        {
            if (!TypeInfoExtensions.GetTypeInfo(type).IsGenericType)
            {
                return(false);
            }
            var g = type.GetGenericTypeDefinition();

            return(g.Equals(typeof(Nullable <>)));
        }
Exemple #3
0
        /// <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]);
        }
Exemple #4
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()));
        }
Exemple #5
0
        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);
                }
            }
        }
Exemple #6
0
        /// <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));
        }
Exemple #7
0
        /// <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);
        }
Exemple #9
0
        /// <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);
        }