Example #1
0
        public BsonMapper(Func <Type, object> customTypeInstantiator = null, ITypeNameBinder typeNameBinder = null)
        {
            this.SerializeNullValues   = false;
            this.TrimWhitespace        = true;
            this.EmptyStringToNull     = true;
            this.EnumAsInteger         = false;
            this.ResolveFieldName      = (s) => s;
            this.ResolveMember         = (t, mi, mm) => { };
            this.ResolveCollectionName = (t) => Reflection.IsEnumerable(t) ? Reflection.GetListItemType(t).Name : t.Name;
            this.IncludeFields         = false;
            this.MaxDepth = 20;

            _typeInstantiator = customTypeInstantiator ?? ((Type t) => null);
            _typeNameBinder   = typeNameBinder ?? DefaultTypeNameBinder.Instance;

            #region Register CustomTypes

            RegisterType <Uri>(uri => uri.AbsoluteUri, bson => new Uri(bson.AsString));
            RegisterType <DateTimeOffset>(value => new BsonValue(value.UtcDateTime), bson => bson.AsDateTime.ToUniversalTime());
            RegisterType <TimeSpan>(value => new BsonValue(value.Ticks), bson => new TimeSpan(bson.AsInt64));
            RegisterType <Regex>(
                r => r.Options == RegexOptions.None ? new BsonValue(r.ToString()) : new BsonDocument {
                { "p", r.ToString() }, { "o", (int)r.Options }
            },
                value => value.IsString ? new Regex(value) : new Regex(value.AsDocument["p"].AsString, (RegexOptions)value.AsDocument["o"].AsInt32)
                );


            #endregion
        }
Example #2
0
        /// <summary>
        /// Try find a Type Resolver for declaring type
        /// </summary>
        private bool TryGetResolver(Type declaringType, out ITypeResolver typeResolver)
        {
            // get method declaring type - if is from any kind of list, read as Enumerable
            var isCollection = Reflection.IsCollection(declaringType);
            var isEnumerable = Reflection.IsEnumerable(declaringType);
            var isNullable   = Reflection.IsNullable(declaringType);

            var type =
                isCollection ? typeof(ICollection) :
                isEnumerable ? typeof(Enumerable) :
                isNullable ? typeof(Nullable) :
                declaringType;

            return(_resolver.TryGetValue(type, out typeResolver));
        }
Example #3
0
        /// <summary>
        /// Use this method to override how your class can be, by default, mapped from entity to Bson document.
        /// Returns an EntityMapper from each requested Type
        /// </summary>
        protected virtual EntityMapper BuildEntityMapper(Type type)
        {
            var mapper = new EntityMapper(type);

            var idAttr     = typeof(BsonIdAttribute);
            var ignoreAttr = typeof(BsonIgnoreAttribute);
            var fieldAttr  = typeof(BsonFieldAttribute);
            var dbrefAttr  = typeof(BsonRefAttribute);

            var members = this.GetTypeMembers(type);
            var id      = this.GetIdMember(members);

            foreach (var memberInfo in members)
            {
                // checks [BsonIgnore]
                if (CustomAttributeExtensions.IsDefined(memberInfo, ignoreAttr, true))
                {
                    continue;
                }

                // checks field name conversion
                var name = this.ResolveFieldName(memberInfo.Name);

                // check if property has [BsonField]
                var field = (BsonFieldAttribute)CustomAttributeExtensions.GetCustomAttributes(memberInfo, fieldAttr, true).FirstOrDefault();

                // check if property has [BsonField] with a custom field name
                if (field != null && field.Name != null)
                {
                    name = field.Name;
                }

                // checks if memberInfo is id field
                if (memberInfo == id)
                {
                    name = "_id";
                }

                // create getter/setter function
                var getter = Reflection.CreateGenericGetter(type, memberInfo);
                var setter = Reflection.CreateGenericSetter(type, memberInfo);

                // check if property has [BsonId] to get with was setted AutoId = true
                var autoId = (BsonIdAttribute)CustomAttributeExtensions.GetCustomAttributes(memberInfo, idAttr, true).FirstOrDefault();

                // get data type
                var dataType = memberInfo is PropertyInfo ?
                               (memberInfo as PropertyInfo).PropertyType :
                               (memberInfo as FieldInfo).FieldType;

                // check if datatype is list/array
                var isEnumerable = Reflection.IsEnumerable(dataType);

                // create a property mapper
                var member = new MemberMapper
                {
                    AutoId         = autoId == null ? true : autoId.AutoId,
                    FieldName      = name,
                    MemberName     = memberInfo.Name,
                    DataType       = dataType,
                    IsEnumerable   = isEnumerable,
                    UnderlyingType = isEnumerable ? Reflection.GetListItemType(dataType) : dataType,
                    Getter         = getter,
                    Setter         = setter
                };

                // check if property has [BsonRef]
                var dbRef = (BsonRefAttribute)CustomAttributeExtensions.GetCustomAttributes(memberInfo, dbrefAttr, false).FirstOrDefault();

                if (dbRef != null && memberInfo is PropertyInfo)
                {
                    BsonMapper.RegisterDbRef(this, member, _typeNameBinder, dbRef.Collection ?? this.ResolveCollectionName((memberInfo as PropertyInfo).PropertyType));
                }

                // support callback to user modify member mapper
                this.ResolveMember?.Invoke(type, memberInfo, member);

                // test if has name and there is no duplicate field
                if (member.FieldName != null && mapper.Members.Any(x => x.FieldName.Equals(name, StringComparison.OrdinalIgnoreCase)) == false)
                {
                    mapper.Members.Add(member);
                }
            }

            return(mapper);
        }