/***************************************************/ 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)); } }
/***************************************************/ /**** 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); } } } }