public void constructor_should_initialize_instance() { var subject = new ObjectSerializer(); subject._discriminatorConvention().Should().Be(BsonSerializer.LookupDiscriminatorConvention(typeof(object))); subject._guidRepresentation().Should().Be(GuidRepresentation.Unspecified); }
public void Deserialize_binary_data_should_return_expected_result_when_guid_representation_is_specified( [ClassValues(typeof(GuidModeValues))] GuidMode mode, [Values(-1, GuidRepresentation.Unspecified)] GuidRepresentation readerGuidRepresentation, [Values(GuidRepresentation.CSharpLegacy, GuidRepresentation.JavaLegacy, GuidRepresentation.PythonLegacy, GuidRepresentation.Standard)] GuidRepresentation guidRepresentation) { #pragma warning disable 618 mode.Set(); var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); var subject = new ObjectSerializer(discriminatorConvention, guidRepresentation); var bytes = new byte[] { 29, 0, 0, 0, 5, 120, 0, 16, 0, 0, 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0 }; var subType = GuidConverter.GetSubType(guidRepresentation); bytes[11] = (byte)subType; var readerSettings = new BsonBinaryReaderSettings(); if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2) { readerSettings.GuidRepresentation = readerGuidRepresentation == (GuidRepresentation)(-1) ? guidRepresentation : GuidRepresentation.Unspecified; } using (var memoryStream = new MemoryStream(bytes)) using (var reader = new BsonBinaryReader(memoryStream, readerSettings)) { var context = BsonDeserializationContext.CreateRoot(reader); reader.ReadStartDocument(); reader.ReadName("x"); var result = subject.Deserialize <object>(context); var guidBytes = bytes.Skip(12).Take(16).ToArray(); var expectedResult = GuidConverter.FromBytes(guidBytes, guidRepresentation); result.Should().Be(expectedResult); } #pragma warning restore 618 }
public void Deserialize_binary_data_should_throw_when_guid_representation_is_specified_and_sub_type_is_not_expected_sub_type( [ClassValues(typeof(GuidModeValues))] GuidMode mode, [Values(GuidRepresentation.CSharpLegacy, GuidRepresentation.JavaLegacy, GuidRepresentation.PythonLegacy, GuidRepresentation.Standard)] GuidRepresentation readerGuidRepresentation, [Values(GuidRepresentation.CSharpLegacy, GuidRepresentation.JavaLegacy, GuidRepresentation.PythonLegacy, GuidRepresentation.Standard)] GuidRepresentation guidRepresentation) { #pragma warning disable 618 mode.Set(); var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); var subject = new ObjectSerializer(discriminatorConvention, guidRepresentation); var bytes = new byte[] { 29, 0, 0, 0, 5, 120, 0, 16, 0, 0, 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0 }; var incorrectSubType = guidRepresentation == GuidRepresentation.Standard ? BsonBinarySubType.UuidLegacy : BsonBinarySubType.UuidStandard; bytes[11] = (byte)incorrectSubType; var readerSettings = new BsonBinaryReaderSettings(); if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2) { readerSettings.GuidRepresentation = readerGuidRepresentation; } using (var memoryStream = new MemoryStream(bytes)) using (var reader = new BsonBinaryReader(memoryStream, readerSettings)) { var context = BsonDeserializationContext.CreateRoot(reader); reader.ReadStartDocument(); reader.ReadName("x"); var exception = Record.Exception(() => subject.Deserialize <object>(context)); exception.Should().BeOfType <FormatException>(); } #pragma warning restore 618 }
public override IAggregateFluent <TNewResult> OfType <TNewResult>(IBsonSerializer <TNewResult> newResultSerializer) { var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(TResult)); if (discriminatorConvention == null) { var message = string.Format("OfType requires that a discriminator convention exist for type: {0}.", BsonUtils.GetFriendlyTypeName(typeof(TResult))); throw new NotSupportedException(message); } var discriminatorValue = discriminatorConvention.GetDiscriminator(typeof(TResult), typeof(TNewResult)); var ofTypeFilter = new BsonDocument(discriminatorConvention.ElementName, discriminatorValue); const string operatorName = "$match"; var stage = new DelegatedPipelineStageDefinition <TResult, TNewResult>( operatorName, (s, sr) => { return(new RenderedPipelineStageDefinition <TNewResult>( operatorName, new BsonDocument(operatorName, ofTypeFilter), newResultSerializer ?? (s as IBsonSerializer <TNewResult>) ?? sr.GetSerializer <TNewResult>())); }); return(AppendStage <TNewResult>(stage)); }
// public methods /// <summary> /// Deserializes an object from a BsonReader. /// </summary> /// <param name="bsonReader">The BsonReader.</param> /// <param name="nominalType">The nominal type of the object.</param> /// <param name="actualType">The actual type of the object.</param> /// <param name="options">The serialization options.</param> /// <returns>An object.</returns> public override object Deserialize( BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) { var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options); var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions; var bsonType = bsonReader.GetCurrentBsonType(); switch (bsonType) { case BsonType.Null: bsonReader.ReadNull(); return(null); case BsonType.Array: var instance = CreateInstance(actualType); var itemDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); Type lastItemType = null; IBsonSerializer lastItemSerializer = null; bsonReader.ReadStartArray(); while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { var itemType = itemDiscriminatorConvention.GetActualType(bsonReader, typeof(object)); IBsonSerializer itemSerializer; if (itemType == lastItemType) { itemSerializer = lastItemSerializer; } else { itemSerializer = BsonSerializer.LookupSerializer(itemType); lastItemType = itemType; lastItemSerializer = itemSerializer; } var item = itemSerializer.Deserialize(bsonReader, typeof(object), itemType, itemSerializationOptions); AddItem(instance, item); } bsonReader.ReadEndArray(); return(FinalizeResult(instance, actualType)); case BsonType.Document: bsonReader.ReadStartDocument(); bsonReader.ReadString("_t"); // skip over discriminator bsonReader.ReadName("_v"); var value = Deserialize(bsonReader, actualType, actualType, options); bsonReader.ReadEndDocument(); return(value); default: var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType); throw new FileFormatException(message); } }
private void SerializeDiscriminator(BsonSerializationContext context, Type nominalType, object obj) { IDiscriminatorConvention discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(_classMap.ClassType); BsonValue discriminator = discriminatorConvention?.GetDiscriminator(nominalType, obj.GetType()); if (discriminator != null) { context.Writer.WriteName(discriminatorConvention.ElementName); BsonValueSerializer.Instance.Serialize(context, discriminator); } }
public MongoStore( ILogger <MongoStore> logger, IClientSessionHandle session, IMongoCollection <Envelope> events, IMongoCollection <Snapshot> snapshots ) { _logger = logger; _session = session; _events = events; _snapshots = snapshots; _discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); }
/// <summary> /// Gets the discriminator convention for values. /// </summary> /// <returns>The discriminator convention for the class.</returns> private IDiscriminatorConvention GetValueDiscriminatorConvention() { // return a cached discriminator convention when possible var discriminatorConvention = _cachedValueDiscriminatorConvention; if (discriminatorConvention == null) { // it's possible but harmless for multiple threads to do the initial lookup at the same time discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(TValue)); _cachedValueDiscriminatorConvention = discriminatorConvention; } return(discriminatorConvention); }
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(); }
public void SerializeBsonValue(object obj, BsonSerializingContext context) { if (obj == null) { context.BsonWriter.WriteNull(); } else if (obj is IEntityHandlerProvider provider) { provider.GetHandler().SerializeBson(context); } else { var s = BsonSerializer.LookupDiscriminatorConvention(obj.GetType()); BsonSerializer.Serialize(context.BsonWriter, obj.GetType(), obj); } }
// public methods /// <summary> /// Deserializes a document from a BsonReader. /// </summary> /// <param name="bsonReader">The BsonReader.</param> /// <param name="nominalType">The nominal type of the document.</param> /// <param name="options">The serialization options.</param> /// <returns>A document.</returns> public override object Deserialize( BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options) { if (!nominalType.IsInterface) { var message = string.Format("Nominal type must be an interface, not {0}.", nominalType.FullName); throw new ArgumentException(message, "nominalType"); } var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(nominalType); var actualType = discriminatorConvention.GetActualType(bsonReader, nominalType); return(Deserialize(bsonReader, nominalType, actualType, options)); }
protected override UpdateDefinition <TDerivedDocument> AdjustUpdateDefinition(UpdateDefinition <TDerivedDocument> updateDefinition, bool isUpsert) { var result = base.AdjustUpdateDefinition(updateDefinition, isUpsert); if (isUpsert) { var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(TDerivedDocument)); var discriminatorValue = discriminatorConvention.GetDiscriminator(typeof(TRootDocument), typeof(TDerivedDocument)); var builder = new UpdateDefinitionBuilder <TDerivedDocument>(); var setOnInsertDiscriminator = builder.SetOnInsert(discriminatorConvention.ElementName, discriminatorValue); result = builder.Combine(result, setOnInsertDiscriminator); } return(result); }
public static (AstFilterField, AstFilter) Translate(TranslationContext context, Expression sourceExpression) { if (sourceExpression is MethodCallExpression sourceMethodCallExpression) { var method = sourceMethodCallExpression.Method; var arguments = sourceMethodCallExpression.Arguments; if (method.Is(EnumerableMethod.OfType)) { var ofTypeSourceExpression = arguments[0]; var(sourceField, sourceFilter) = Translate(context, ofTypeSourceExpression); var nominalType = ArraySerializerHelper.GetItemSerializer(sourceField.Serializer).ValueType; var actualType = method.GetGenericArguments()[0]; var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(actualType); var discriminatorField = AstFilter.Field(discriminatorConvention.ElementName, BsonValueSerializer.Instance); var discriminatorValue = discriminatorConvention.GetDiscriminator(nominalType, actualType); var ofTypeFilter = AstFilter.Eq(discriminatorField, discriminatorValue); var actualTypeSerializer = context.KnownSerializersRegistry.GetSerializer(sourceExpression); var enumerableActualTypeSerializer = IEnumerableSerializer.Create(actualTypeSerializer); var actualTypeSourceField = AstFilter.Field(sourceField.Path, enumerableActualTypeSerializer); var combinedFilter = AstFilter.Combine(sourceFilter, ofTypeFilter); return(actualTypeSourceField, combinedFilter); } if (method.Is(EnumerableMethod.Where)) { var whereSourceExpression = arguments[0]; var(sourceField, sourceFilter) = Translate(context, whereSourceExpression); var predicateLambda = (LambdaExpression)arguments[1]; var parameterExpression = predicateLambda.Parameters.Single(); var itemSerializer = ArraySerializerHelper.GetItemSerializer(sourceField.Serializer); var parameterSymbol = context.CreateSymbol(parameterExpression, "@<elem>", itemSerializer); // @<elem> represents the implied element var predicateContext = context.WithSingleSymbol(parameterSymbol); // @<elem> is the only symbol visible inside an $elemMatch var whereFilter = ExpressionToFilterTranslator.Translate(predicateContext, predicateLambda.Body, exprOk: false); var combinedFilter = AstFilter.Combine(sourceFilter, whereFilter); return(sourceField, combinedFilter); } } var field = ExpressionToFilterFieldTranslator.Translate(context, sourceExpression); return(field, null); }
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); }
// public methods /// <summary> /// Deserializes an object from a BsonReader. /// </summary> /// <param name="bsonReader">The BsonReader.</param> /// <param name="nominalType">The nominal type of the object.</param> /// <param name="actualType">The actual type of the object.</param> /// <param name="options">The serialization options.</param> /// <returns>An object.</returns> public override object Deserialize( BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) { VerifyTypes(nominalType, actualType, typeof(T[])); var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options); var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions; var bsonType = bsonReader.GetCurrentBsonType(); switch (bsonType) { case BsonType.Null: bsonReader.ReadNull(); return(null); case BsonType.Array: bsonReader.ReadStartArray(); var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(T)); var list = new List <T>(); while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(T)); var serializer = BsonSerializer.LookupSerializer(elementType); var element = (T)serializer.Deserialize(bsonReader, typeof(T), elementType, itemSerializationOptions); list.Add(element); } bsonReader.ReadEndArray(); return(list.ToArray()); case BsonType.Document: bsonReader.ReadStartDocument(); bsonReader.ReadString("_t"); // skip over discriminator bsonReader.ReadName("_v"); var value = Deserialize(bsonReader, actualType, actualType, options); bsonReader.ReadEndDocument(); return(value); default: var message = string.Format("Can't deserialize a {0} from BsonType {1}.", actualType.FullName, bsonType); throw new FileFormatException(message); } }
public static AstFilter Translate(TranslationContext context, TypeBinaryExpression expression) { if (expression.NodeType == ExpressionType.TypeIs) { var fieldExpression = expression.Expression; var field = ExpressionToFilterFieldTranslator.Translate(context, fieldExpression); var nominalType = fieldExpression.Type; var actualType = expression.TypeOperand; var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(actualType); var discriminatorField = field.SubField(discriminatorConvention.ElementName, BsonValueSerializer.Instance); var discriminator = discriminatorConvention.GetDiscriminator(nominalType, actualType); return(AstFilter.Eq(discriminatorField, discriminator)); } throw new ExpressionNotSupportedException(expression); }
// public methods /// <summary> /// Deserializes an object from a BsonReader. /// </summary> /// <param name="bsonReader">The BsonReader.</param> /// <param name="nominalType">The nominal type of the object.</param> /// <param name="options">The serialization options.</param> /// <returns>An object.</returns> public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options) { if (nominalType != typeof(object)) { var message = string.Format("ObjectSerializer can only be used with nominal type System.Object, not type {0}.", nominalType.FullName); throw new InvalidOperationException(message); } var bsonType = bsonReader.GetCurrentBsonType(); if (bsonType == BsonType.Null) { bsonReader.ReadNull(); return(null); } else if (bsonType == BsonType.Document) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); if (bsonReader.ReadBsonType() == BsonType.EndOfDocument) { bsonReader.ReadEndDocument(); return(new object()); } else { bsonReader.ReturnToBookmark(bookmark); } } var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); var actualType = discriminatorConvention.GetActualType(bsonReader, typeof(object)); if (actualType == typeof(object)) { var message = string.Format("Unable to determine actual type of object to deserialize. NominalType is System.Object and BsonType is {0}.", bsonType); throw new FileFormatException(message); } var serializer = BsonSerializer.LookupSerializer(actualType); return(serializer.Deserialize(bsonReader, nominalType, actualType, options)); }
public void Serialize_guid_should_have_expected_result_when_guid_representation_is_unspecified_and_mode_is_v2( [Values(GuidRepresentation.CSharpLegacy, GuidRepresentation.JavaLegacy, GuidRepresentation.PythonLegacy, GuidRepresentation.Standard, GuidRepresentation.Unspecified)] GuidRepresentation defaultGuidRepresentation, [Values(GuidRepresentation.CSharpLegacy, GuidRepresentation.JavaLegacy, GuidRepresentation.PythonLegacy, GuidRepresentation.Standard, GuidRepresentation.Unspecified)] GuidRepresentation writerGuidRepresentation) { #pragma warning disable 618 var expectedGuidRepresentation = writerGuidRepresentation != GuidRepresentation.Unspecified ? writerGuidRepresentation : defaultGuidRepresentation; if (expectedGuidRepresentation == GuidRepresentation.Unspecified) { throw new SkipException("Test skipped because expectedGuidRepresentation is Unspecified."); } BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V2; BsonDefaults.GuidRepresentation = defaultGuidRepresentation; var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); var subject = new ObjectSerializer(discriminatorConvention, GuidRepresentation.Unspecified); var writerSettings = new BsonBinaryWriterSettings(); if (writerGuidRepresentation != GuidRepresentation.Unspecified) { writerSettings.GuidRepresentation = writerGuidRepresentation; } using (var memoryStream = new MemoryStream()) using (var writer = new BsonBinaryWriter(memoryStream, writerSettings)) { var context = BsonSerializationContext.CreateRoot(writer); var guid = Guid.Parse("01020304-0506-0708-090a-0b0c0d0e0f10"); writer.WriteStartDocument(); writer.WriteName("x"); subject.Serialize(context, guid); writer.WriteEndDocument(); var bytes = memoryStream.ToArray(); var expectedBytes = new byte[] { 29, 0, 0, 0, 5, 120, 0, 16, 0, 0, 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0 }; var expectedSubType = GuidConverter.GetSubType(expectedGuidRepresentation); var expectedGuidBytes = GuidConverter.ToBytes(guid, expectedGuidRepresentation); expectedBytes[11] = (byte)expectedSubType; Array.Copy(expectedGuidBytes, 0, expectedBytes, 12, 16); bytes.Should().Equal(expectedBytes); } #pragma warning restore 618 }
public void Deserialize_binary_data_should_throw_when_guid_representation_is_unspecified_and_mode_is_v3() { #pragma warning disable 618 BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3; var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); var subject = new ObjectSerializer(discriminatorConvention, GuidRepresentation.Unspecified); var bytes = new byte[] { 29, 0, 0, 0, 5, 120, 0, 16, 0, 0, 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0 }; using (var memoryStream = new MemoryStream(bytes)) using (var reader = new BsonBinaryReader(memoryStream)) { var context = BsonDeserializationContext.CreateRoot(reader); reader.ReadStartDocument(); reader.ReadName("x"); var exception = Record.Exception(() => subject.Deserialize <object>(context)); exception.Should().BeOfType <BsonSerializationException>(); } #pragma warning restore 618 }
public void Serialize_guid_should_throw_when_guid_representation_is_unspecified_and_mode_is_v3() { #pragma warning disable 618 BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3; var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); var subject = new ObjectSerializer(discriminatorConvention, GuidRepresentation.Unspecified); using (var memoryStream = new MemoryStream()) using (var writer = new BsonBinaryWriter(memoryStream)) { var context = BsonSerializationContext.CreateRoot(writer); var guid = Guid.Parse("01020304-0506-0708-090a-0b0c0d0e0f10"); writer.WriteStartDocument(); writer.WriteName("x"); var exception = Record.Exception(() => subject.Serialize(context, guid)); exception.Should().BeOfType <BsonSerializationException>(); } #pragma warning restore 618 }
// public static methods public static AstPipeline Translate(TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (method.Is(QueryableMethod.OfType)) { var sourceExpression = arguments[0]; var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression); var sourceType = sourceExpression.Type; var nominalType = sourceType.GetGenericArguments()[0]; var actualType = method.GetGenericArguments()[0]; var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(nominalType); var discriminatorElementName = discriminatorConvention.ElementName; var wrappedValueOutputSerializer = pipeline.OutputSerializer as IWrappedValueSerializer; if (wrappedValueOutputSerializer != null) { discriminatorElementName = wrappedValueOutputSerializer.FieldName + "." + discriminatorElementName; } var discriminatorField = AstFilter.Field(discriminatorElementName, BsonValueSerializer.Instance); var discriminatorValue = discriminatorConvention.GetDiscriminator(nominalType, actualType); var filter = AstFilter.Eq(discriminatorField, discriminatorValue); // note: OfType only works with hierarchical discriminators var actualSerializer = context.KnownSerializersRegistry.GetSerializer(expression); if (wrappedValueOutputSerializer != null) { actualSerializer = WrappedValueSerializer.Create(wrappedValueOutputSerializer.FieldName, actualSerializer); } pipeline = pipeline.AddStages( actualSerializer, AstStage.Match(filter)); return(pipeline); } throw new ExpressionNotSupportedException(expression); }
// public methods /// <summary> /// Deserializes an Image from a BsonReader. /// </summary> /// <param name="bsonReader">The BsonReader.</param> /// <param name="nominalType">The nominal type of the Image.</param> /// <param name="options">The serialization options.</param> /// <returns>An Image.</returns> public override object Deserialize( BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options) { if (nominalType != typeof(Image)) { var message = string.Format("Nominal type must be Image, not {0}.", nominalType.FullName); throw new ArgumentException(message, "nominalType"); } var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(Image)); var actualType = discriminatorConvention.GetActualType(bsonReader, typeof(Image)); if (actualType == typeof(Image)) { var message = string.Format("Unable to determine actual type of Image to deserialize."); throw new FileFormatException(message); } var serializer = BsonSerializer.LookupSerializer(actualType); return(serializer.Deserialize(bsonReader, nominalType, actualType, options)); }
/// <summary> /// Gets the actual type. /// </summary> /// <param name="context">The context.</param> /// <returns>The actual type.</returns> protected virtual Type GetActualType(BsonDeserializationContext context) { var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(TValue)); return(discriminatorConvention.GetActualType(context.Reader, typeof(TValue))); }
// constructors /// <summary> /// Initializes a new instance of the <see cref="DiscriminatedInterfaceSerializer{TInterface}" /> class. /// </summary> public DiscriminatedInterfaceSerializer() : this(BsonSerializer.LookupDiscriminatorConvention(typeof(TInterface))) { }
private void TranslateOfType(MethodCallExpression methodCallExpression) { var method = methodCallExpression.Method; if (method.DeclaringType != typeof(Queryable)) { var message = string.Format("OfType method of class {0} is not supported.", BsonUtils.GetFriendlyTypeName(method.DeclaringType)); throw new NotSupportedException(message); } if (!method.IsStatic) { throw new NotSupportedException("Expected OfType to be a static method."); } if (!method.IsGenericMethod) { throw new NotSupportedException("Expected OfType to be a generic method."); } var actualType = method.GetGenericArguments()[0]; var args = methodCallExpression.Arguments.ToArray(); if (args.Length != 1) { throw new NotSupportedException("Expected OfType method to have a single argument."); } var sourceExpression = args[0]; if (!sourceExpression.Type.IsGenericType) { throw new NotSupportedException("Expected source argument to OfType to be a generic type."); } var nominalType = sourceExpression.Type.GetGenericArguments()[0]; if (_projection != null) { throw new NotSupportedException("OfType after a projection is not supported."); } var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(nominalType); var discriminator = discriminatorConvention.GetDiscriminator(nominalType, actualType); if (discriminator == null) { return; // nothing to do } if (discriminator.IsBsonArray) { discriminator = discriminator.AsBsonArray[discriminator.AsBsonArray.Count - 1]; } var query = Query.EQ(discriminatorConvention.ElementName, discriminator); var injectMethodInfo = typeof(LinqToMongo).GetMethod("Inject"); var body = Expression.Call(injectMethodInfo, Expression.Constant(query)); var parameter = Expression.Parameter(nominalType, "x"); var predicate = Expression.Lambda(body, parameter); CombinePredicateWithWhereClause(methodCallExpression, predicate); _ofType = actualType; }
// public methods /// <summary> /// Deserializes an object from a BsonReader. /// </summary> /// <param name="bsonReader">The BsonReader.</param> /// <param name="nominalType">The nominal type of the object.</param> /// <param name="actualType">The actual type of the object.</param> /// <param name="options">The serialization options.</param> /// <returns>An object.</returns> public override object Deserialize( BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) { var dictionarySerializationOptions = EnsureSerializationOptions(options); var keyValuePairSerializationOptions = dictionarySerializationOptions.KeyValuePairSerializationOptions; var bsonType = bsonReader.GetCurrentBsonType(); if (bsonType == BsonType.Null) { bsonReader.ReadNull(); return(null); } else if (bsonType == BsonType.Document) { if (nominalType == typeof(object)) { bsonReader.ReadStartDocument(); bsonReader.ReadString("_t"); // skip over discriminator bsonReader.ReadName("_v"); var value = Deserialize(bsonReader, actualType, options); // recursive call replacing nominalType with actualType bsonReader.ReadEndDocument(); return(value); } var dictionary = CreateInstance(actualType); var valueDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); bsonReader.ReadStartDocument(); while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { var key = bsonReader.ReadName(); var valueType = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(object)); var valueSerializer = BsonSerializer.LookupSerializer(valueType); var value = valueSerializer.Deserialize(bsonReader, typeof(object), valueType, keyValuePairSerializationOptions.ValueSerializationOptions); dictionary.Add(key, value); } bsonReader.ReadEndDocument(); return(dictionary); } else if (bsonType == BsonType.Array) { var dictionary = CreateInstance(actualType); bsonReader.ReadStartArray(); while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { var keyValuePair = (KeyValuePair <object, object>)_keyValuePairSerializer.Deserialize( bsonReader, typeof(KeyValuePair <object, object>), keyValuePairSerializationOptions); dictionary.Add(keyValuePair.Key, keyValuePair.Value); } bsonReader.ReadEndArray(); return(dictionary); } else { var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType); throw new Exception(message); } }
// public methods /// <summary> /// Deserializes an object from a BsonReader. /// </summary> /// <param name="bsonReader">The BsonReader.</param> /// <param name="nominalType">The nominal type of the object.</param> /// <param name="actualType">The actual type of the object.</param> /// <param name="options">The serialization options.</param> /// <returns>An object.</returns> public override object Deserialize( BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) { VerifyTypes(nominalType, actualType, typeof(T[, ])); var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options); var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions; var bsonType = bsonReader.GetCurrentBsonType(); string message; switch (bsonType) { case BsonType.Null: bsonReader.ReadNull(); return(null); case BsonType.Array: var itemNominalType = typeof(T); var itemNominalTypeIsValueType = itemNominalType.IsValueType; var itemNominalTypeSerializer = BsonSerializer.LookupSerializer(itemNominalType); var itemDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(itemNominalType); Type lastItemType = null; IBsonSerializer lastItemSerializer = null; // if itemNominalType is a value type then these assignments are final var itemActualType = itemNominalType; var itemActualTypeSerializer = itemNominalTypeSerializer; bsonReader.ReadStartArray(); var outerList = new List <List <T> >(); while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { bsonReader.ReadStartArray(); var innerList = new List <T>(); while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { if (!itemNominalTypeIsValueType) { itemActualType = itemDiscriminatorConvention.GetActualType(bsonReader, itemNominalType); if (itemActualType == itemNominalType) { itemActualTypeSerializer = itemNominalTypeSerializer; } else if (itemActualType == lastItemType) { itemActualTypeSerializer = lastItemSerializer; } else { itemActualTypeSerializer = BsonSerializer.LookupSerializer(itemActualType); lastItemType = itemActualType; lastItemSerializer = itemActualTypeSerializer; } } var item = (T)itemActualTypeSerializer.Deserialize(bsonReader, itemNominalType, itemActualType, itemSerializationOptions); innerList.Add(item); } bsonReader.ReadEndArray(); outerList.Add(innerList); } bsonReader.ReadEndArray(); var length1 = outerList.Count; var length2 = (length1 == 0) ? 0 : outerList[0].Count; var array = new T[length1, length2]; for (int i = 0; i < length1; i++) { var innerList = outerList[i]; if (innerList.Count != length2) { message = string.Format("Inner list {0} is of length {1} but should be of length {2}.", i, innerList.Count, length2); throw new FileFormatException(message); } for (int j = 0; j < length2; j++) { array[i, j] = innerList[j]; } } return(array); case BsonType.Document: bsonReader.ReadStartDocument(); bsonReader.ReadString("_t"); // skip over discriminator bsonReader.ReadName("_v"); var value = Deserialize(bsonReader, actualType, actualType, options); bsonReader.ReadEndDocument(); return(value); default: message = string.Format("Can't deserialize a {0} from BsonType {1}.", actualType.FullName, bsonType); throw new FileFormatException(message); } }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { var actualType = value.GetType(); VerifyTypes(nominalType, actualType, typeof(T[, ])); if (nominalType == typeof(object)) { bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); bsonWriter.WriteEndDocument(); return; } var array = (T[, ])value; var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options); var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions; var itemNominalType = typeof(T); var itemNominalTypeIsValueType = itemNominalType.IsValueType; var itemNominalTypeSerializer = BsonSerializer.LookupSerializer(itemNominalType); var itemDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(itemNominalType); Type lastItemType = null; IBsonSerializer lastItemSerializer = null; // if itemNominalType is a value type then these assignments are final var itemActualType = itemNominalType; var itemActualTypeSerializer = itemNominalTypeSerializer; bsonWriter.WriteStartArray(); var length1 = array.GetLength(0); var length2 = array.GetLength(1); for (int i = 0; i < length1; i++) { bsonWriter.WriteStartArray(); for (int j = 0; j < length2; j++) { var item = array[i, j]; if (!itemNominalTypeIsValueType) { itemActualType = item == null ? itemNominalType : item.GetType(); if (itemActualType == itemNominalType) { itemActualTypeSerializer = itemNominalTypeSerializer; } else if (itemActualType == lastItemType) { itemActualTypeSerializer = lastItemSerializer; } else { itemActualTypeSerializer = BsonSerializer.LookupSerializer(itemActualType); lastItemType = itemActualType; lastItemSerializer = itemActualTypeSerializer; } } itemActualTypeSerializer.Serialize(bsonWriter, itemNominalType, item, itemSerializationOptions); } bsonWriter.WriteEndArray(); } bsonWriter.WriteEndArray(); } }
// constructors /// <summary> /// Initializes a new instance of the <see cref="ObjectSerializer"/> class. /// </summary> public ObjectSerializer() : this(BsonSerializer.LookupDiscriminatorConvention(typeof(object))) { }
/***************************************************/ /**** Constructors ****/ /***************************************************/ public BH_ObjectSerializer() { _discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); }