예제 #1
0
        // public methods
        /// <summary>
        /// Deserializes a value.
        /// </summary>
        /// <param name="context">The deserialization context.</param>
        /// <param name="args">The deserialization args.</param>
        /// <returns>An object.</returns>
        public override TValue Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var bsonReader  = context.Reader;
            var nominalType = args.NominalType;
            var actualType  = _discriminatorConvention.GetActualType(bsonReader, nominalType);
            var serializer  = BsonSerializer.LookupSerializer(actualType);

            TValue value = default(TValue);

            _helper.DeserializeMembers(context, (elementName, flag) =>
            {
                switch (flag)
                {
                case Flags.Discriminator:
                    bsonReader.SkipValue();
                    break;

                case Flags.Value:
                    var valueDeserializationArgs = new BsonDeserializationArgs {
                        NominalType = actualType
                    };
                    value = (TValue)serializer.Deserialize(context, valueDeserializationArgs);
                    break;
                }
            });

            return(value);
        }
예제 #2
0
        /// <summary>
        /// Deserializes a value.
        /// </summary>
        public override object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var bsonReader = context.Reader;

            if (BsonType.Document == bsonReader.GetCurrentBsonType())
            {
                RegisterNewTypesToDiscriminator(DiscriminatorConvention.GetActualType(bsonReader, typeof(object)));
            }

            return(base.Deserialize(context, args));
        }
예제 #3
0
        public static void Test_DiscriminatorConvention_01(BsonDocument document)
        {
            Trace.WriteLine("Test_DiscriminatorConvention_01");
            BsonReader bsonReader = BsonReader.Create(document);
            IDiscriminatorConvention discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(ZValue));

            Trace.WriteLine("discriminatorConvention(ZValue) : {0}", discriminatorConvention);
            Type actualType = discriminatorConvention.GetActualType(bsonReader, typeof(ZValue));

            Trace.WriteLine("actualType : {0}", actualType);
            //discriminatorConvention.GetDiscriminator()
            Trace.WriteLine();
        }
예제 #4
0
        public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var      bsonReader = context.Reader;
            BsonType bsonType   = bsonReader.CurrentBsonType;

            object result;

            if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                result = null;
            }
            else
            {
                if (bsonType == BsonType.Document)
                {
                    var dictionary = new DynamicDictionary();

                    bsonReader.ReadStartDocument();

                    IDiscriminatorConvention valueDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));

                    while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                    {
                        string          key             = bsonReader.ReadName();
                        Type            valueType       = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(object));
                        IBsonSerializer valueSerializer = BsonSerializer.LookupSerializer(valueType);
                        object          value           = valueSerializer.Deserialize(context);

                        if (key != "_t")
                        {
                            dictionary.Add(key.Replace('\x03', '.'), value);
                        }
                    }
                    bsonReader.ReadEndDocument();
                    result = dictionary;
                }
                else
                {
                    string message = string.Format("Can't deserialize a {0} from BsonType {1}.", context.Reader.CurrentBsonType, bsonType);
                    throw new BsonException(message);
                }
            }

            return(result);
        }
        // private methods
        private object DeserializeDiscriminatedValue(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var bsonReader = context.Reader;

            var actualType = _discriminatorConvention.GetActualType(bsonReader, typeof(object));

            if (actualType == typeof(object))
            {
                var type = bsonReader.GetCurrentBsonType();
                switch (type)
                {
                case BsonType.Document:
                    if (context.DynamicDocumentSerializer != null)
                    {
                        return(context.DynamicDocumentSerializer.Deserialize(context, args));
                    }
                    break;
                }

                bsonReader.ReadStartDocument();
                bsonReader.ReadEndDocument();
                return(new object());
            }
            else
            {
                var serializer            = BsonSerializer.LookupSerializer(actualType);
                var polymorphicSerializer = serializer as IBsonPolymorphicSerializer;
                if (polymorphicSerializer != null && polymorphicSerializer.IsDiscriminatorCompatibleWithObjectSerializer)
                {
                    return(serializer.Deserialize(context, args));
                }
                else
                {
                    bsonReader.ReadStartDocument();
                    bsonReader.ReadName(_discriminatorConvention.ElementName);
                    bsonReader.SkipValue();
                    bsonReader.ReadName("_v");
                    var value = serializer.Deserialize(context);
                    bsonReader.ReadEndDocument();

                    return(value);
                }
            }
        }
예제 #6
0
        // public methods
        /// <summary>
        /// Deserializes a value.
        /// </summary>
        /// <param name="context">The deserialization context.</param>
        /// <returns>
        /// A document.
        /// </returns>
        /// <exception cref="System.FormatException"></exception>
        public override TInterface Deserialize(BsonDeserializationContext context)
        {
            var bsonReader = context.Reader;

            if (bsonReader.GetCurrentBsonType() == BsonType.Null)
            {
                bsonReader.ReadNull();
                return(default(TInterface));
            }
            else
            {
                var actualType = _discriminatorConvention.GetActualType(bsonReader, typeof(TInterface));
                if (actualType == _interfaceType)
                {
                    var message = string.Format("Unable to determine actual type of object to deserialize for interface type {0}.", _interfaceType.FullName);
                    throw new FormatException(message);
                }

                var serializer = BsonSerializer.LookupSerializer(actualType);
                return((TInterface)serializer.Deserialize(context));
            }
        }
예제 #7
0
        // private methods
        private object DeserializeDiscriminatedValue(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var bsonReader = context.Reader;

            var actualType = _discriminatorConvention.GetActualType(bsonReader, typeof(object));

            if (actualType == typeof(object))
            {
                var type = bsonReader.GetCurrentBsonType();
                switch (type)
                {
                case BsonType.Document:
                    if (context.DynamicDocumentSerializer != null)
                    {
                        return(context.DynamicDocumentSerializer.Deserialize(context, args));
                    }
                    break;
                }

                bsonReader.ReadStartDocument();
                bsonReader.ReadEndDocument();
                return(new object());
            }
            else
            {
                var serializer            = BsonSerializer.LookupSerializer(actualType);
                var polymorphicSerializer = serializer as IBsonPolymorphicSerializer;
                if (polymorphicSerializer != null && polymorphicSerializer.IsDiscriminatorCompatibleWithObjectSerializer)
                {
                    return(serializer.Deserialize(context, args));
                }
                else
                {
                    object value           = null;
                    var    wasValuePresent = false;

                    bsonReader.ReadStartDocument();
                    while (bsonReader.ReadBsonType() != 0)
                    {
                        var name = bsonReader.ReadName();
                        if (name == _discriminatorConvention.ElementName)
                        {
                            bsonReader.SkipValue();
                        }
                        else if (name == "_v")
                        {
                            value           = serializer.Deserialize(context);
                            wasValuePresent = true;
                        }
                        else
                        {
                            var message = string.Format("Unexpected element name: '{0}'.", name);
                            throw new FormatException(message);
                        }
                    }
                    bsonReader.ReadEndDocument();

                    if (!wasValuePresent)
                    {
                        throw new FormatException("_v element missing.");
                    }

                    return(value);
                }
            }
        }