Exemplo n.º 1
0
        /***************************************************/

        private object DeserializeDiscriminatedValue(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            // First try to recover the object type
            IBsonReader        reader   = context.Reader;
            BsonReaderBookmark bookmark = reader.GetBookmark();
            Type actualType             = typeof(CustomObject);

            try
            {
                actualType = _discriminatorConvention.GetActualType(reader, typeof(object));
            }
            catch
            {
                try
                {
                    context.Reader.ReturnToBookmark(bookmark);
                    DeprecatedSerializer deprecatedSerialiser = new DeprecatedSerializer();
                    return(deprecatedSerialiser.Deserialize(context, args));
                }
                catch { }
            }
            context.Reader.ReturnToBookmark(bookmark);

            if (actualType == null)
            {
                return(null);
            }

            // Handle the special case where the type is object
            if (actualType == typeof(object))
            {
                BsonType currentBsonType = reader.GetCurrentBsonType();
                if (currentBsonType == BsonType.Document && context.DynamicDocumentSerializer != null)
                {
                    return(context.DynamicDocumentSerializer.Deserialize(context, args));
                }
                reader.ReadStartDocument();
                reader.ReadEndDocument();
                return(new object());
            }

            // Handle the general case of finding the correct deserialiser and calling it
            try
            {
                if (!BsonClassMap.IsClassMapRegistered(actualType))
                {
                    Compute.RegisterClassMap(actualType); // LookupSerializer creates the classMap if it doesn't exist so important to do it through our own method
                }
                IBsonSerializer bsonSerializer = BsonSerializer.LookupSerializer(actualType);

                if (bsonSerializer.GetType().Name == "EnumerableInterfaceImplementerSerializer`2" && context.Reader.CurrentBsonType == BsonType.Document)
                {
                    if (!m_FallbackSerialisers.ContainsKey(actualType))
                    {
                        CreateFallbackSerialiser(actualType);
                    }
                    bsonSerializer = m_FallbackSerialisers[actualType];
                }
                else if (actualType.Name == "Dictionary`2" && context.Reader.CurrentBsonType == BsonType.Document)
                {
                    DictionarySerializer dicSerialiser = new DictionarySerializer();
                    return(dicSerialiser.Deserialize(context, args));
                }

                return(bsonSerializer.Deserialize(context, args));
            }
            catch (Exception e)
            {
                if (e.Message.Contains("Could not load file or assembly"))
                {
                    Engine.Reflection.Compute.RecordError(e.Message);
                }

                context.Reader.ReturnToBookmark(bookmark);
                DeprecatedSerializer deprecatedSerialiser = new DeprecatedSerializer();
                return(deprecatedSerialiser.Deserialize(context, args));
            }
        }
Exemplo n.º 2
0
        /***************************************************/
        /**** Private Helper Methods                    ****/
        /***************************************************/

        private void SerializeDiscriminatedValue(BsonSerializationContext context, BsonSerializationArgs args, object value, Type actualType)
        {
            if (actualType.Name == "RuntimeMethodInfo" || actualType.Name == "RuntimeConstructorInfo")
            {
                actualType = typeof(MethodBase);
            }
            else if (actualType.Name == "RuntimeType")
            {
                actualType = typeof(Type);
            }
            else if (value is Enum)
            {
                actualType = typeof(Enum);
            }

            if (!BsonClassMap.IsClassMapRegistered(actualType))
            {
                Compute.RegisterClassMap(actualType);
            }

            var serializer = BsonSerializer.LookupSerializer(actualType);

            if (serializer.GetType().Name == "EnumerableInterfaceImplementerSerializer`2" && context.Writer.State == BsonWriterState.Initial)
            {
                if (!m_FallbackSerialisers.ContainsKey(actualType))
                {
                    CreateFallbackSerialiser(actualType);
                }
                serializer = m_FallbackSerialisers[actualType];
            }

            var polymorphicSerializer = serializer as IBsonPolymorphicSerializer;

            if (polymorphicSerializer != null && polymorphicSerializer.IsDiscriminatorCompatibleWithObjectSerializer)
            {
                serializer.Serialize(context, args, value);
            }
            else
            {
                if (context.IsDynamicType != null && context.IsDynamicType(value.GetType()))
                {
                    args.NominalType = actualType;
                    serializer.Serialize(context, args, value);
                }
                else
                {
                    var bsonWriter = context.Writer;
                    if (actualType.Name == "Dictionary`2")
                    {
                        Type keyType = actualType.GenericTypeArguments[0];
                        if (keyType == typeof(string))
                        {
                            serializer.Serialize(context, value);
                        }
                        else
                        {
                            DictionarySerializer dicSerialiser = new DictionarySerializer();
                            dicSerialiser.Serialize(context, value);
                        }
                    }
                    else
                    {
                        serializer.Serialize(context, value);
                    }
                }
            }
        }