Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 828ea90d94
Fetching contributors…

Cannot retrieve contributors at this time

file 97 lines (84 sloc) 3.938 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
using System;
using System.Collections.Generic;
using MongoDB.Configuration.Mapping.Model;
using MongoDB.Configuration.Mapping;
using MongoDB.Bson;

namespace MongoDB.Serialization.Descriptors
{
    internal class ClassMapPropertyDescriptor : ClassMapPropertyDescriptorBase
    {
        private readonly object _instance;
        private readonly IDictionary<string, object> _extendedProperties;

        /// <summary>
        /// Initializes a new instance of the <see cref="ClassMapPropertyDescriptor"/> class.
        /// </summary>
        /// <param name="mappingStore">The mapping store.</param>
        /// <param name="classMap">The class map.</param>
        /// <param name="instance">The instance.</param>
        public ClassMapPropertyDescriptor(IMappingStore mappingStore, IClassMap classMap, object instance)
            : base(mappingStore, classMap)
        {
            if (instance == null)
                throw new ArgumentNullException("instance");

            _instance = instance;
            if (ClassMap.HasExtendedProperties)
                _extendedProperties = (IDictionary<string, object>)ClassMap.ExtendedPropertiesMap.GetValue(instance);
        }

        /// <summary>
        /// Gets the property names.
        /// </summary>
        /// <returns></returns>
        public override IEnumerable<BsonProperty> GetProperties()
        {
            if (ClassMap.HasId)
                yield return CreateProperty(ClassMap.IdMap.Alias, ClassMap.IdMap.MemberReturnType, ClassMap.GetId(_instance), false);

            if (ShouldPersistDiscriminator())
                yield return CreateProperty(ClassMap.DiscriminatorAlias, ClassMap.Discriminator.GetType(), ClassMap.Discriminator, false);

            foreach (var memberMap in ClassMap.MemberMaps)
            {
                var value = GetValue(memberMap.MemberName);
                if (!memberMap.PersistDefaultValue && object.Equals(memberMap.DefaultValue, value))
                    continue;
                yield return CreateProperty(memberMap.Alias, value);
            }

            if (_extendedProperties == null)
                yield break;

            foreach(var propertyName in _extendedProperties.Keys)
                yield return CreateProperty(propertyName, GetValue(propertyName));
        }

        /// <summary>
        /// Gets the value.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        private BsonPropertyValue GetValue(string name)
        {
            if (ClassMap.DiscriminatorAlias == name && ShouldPersistDiscriminator())
                return new BsonPropertyValue(ClassMap.Discriminator.GetType(), ClassMap.Discriminator, false);
            
            object value;

            var memberMap = GetAliasFromMemberName(name).MemberMap;
            if(memberMap != null)
                value = memberMap.GetValue(_instance);
            else if (_extendedProperties != null)
                value = _extendedProperties[name];
            else
                throw new InvalidOperationException("Attempting to get a property that does not exist.");

            var type = typeof(Document);
            bool isDictionary = false;
            if (memberMap != null)
            {
                type = memberMap.MemberReturnType;
                if (memberMap is CollectionMemberMap)
                    type = ((CollectionMemberMap)memberMap).ElementType;
                else if (memberMap is DictionaryMemberMap)
                {
                    type = ((DictionaryMemberMap)memberMap).ValueType;
                    isDictionary = true;
                }
            }
            else if (value != null)
                type = value.GetType();

            return new BsonPropertyValue(type, value, isDictionary);
        }
    }
}
Something went wrong with that request. Please try again.