Skip to content

CSHARP-3985: Support multiple SerializerRegistries #1592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 53 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
3c99f6d
Rebase commit
papafe May 26, 2025
d087b6c
Corrected type
papafe May 26, 2025
975545a
Various improvements, and added test for discriminators.
papafe May 26, 2025
ecd84a8
Removed comment.
papafe May 26, 2025
a4d92cc
Small corrections.
papafe May 26, 2025
7280ac5
Small correction.
papafe May 26, 2025
27ccb7b
Corrected test
papafe May 26, 2025
e589695
Correction for test
papafe May 26, 2025
5efa4da
Correction
papafe May 26, 2025
962861f
Removed new tests untul refactoring
papafe May 26, 2025
0b92d63
Added domain to MongoQueryProvider
papafe May 27, 2025
6d5fb86
Small fix
papafe May 27, 2025
d1585d1
Corrected freeze
papafe May 27, 2025
5e6931c
Small correction
papafe May 27, 2025
e6b8b35
Fixed BsonClassMap.Freeze and Convention Apply
papafe May 27, 2025
818dc7e
Small fix.
papafe Jun 4, 2025
543c396
Corrected test
papafe Jun 4, 2025
f07be62
Made conventions internal
papafe Jun 4, 2025
f845894
Corrected accessibility
papafe Jun 4, 2025
a3afabb
Fixed discriminator method
papafe Jun 12, 2025
1791906
Simplified
papafe Jun 12, 2025
3a2b361
Hide IBsonReader settings
papafe Jun 12, 2025
fe78c71
Other improvements
papafe Jun 12, 2025
63a8b64
Added constructor to avoid api compat issue
papafe Jun 13, 2025
a641602
Correct
papafe Jun 13, 2025
ef7a962
Small fixes
papafe Jun 13, 2025
b489c38
Various fixes
papafe Jun 13, 2025
cacf077
Added BsonDefaults to domain
papafe Jun 16, 2025
6ccc864
Various fixes to hide API
papafe Jun 16, 2025
4a5220a
Small things
papafe Jun 17, 2025
697784b
Builders example
papafe Jun 17, 2025
97fd948
Removed references to certain parts of BsonDefaults.
papafe Jun 20, 2025
ecf6f92
Various fixes
papafe Jun 20, 2025
7271903
Moved to internal 1
papafe Jun 25, 2025
e513938
More internal
papafe Jun 25, 2025
4c5bdcc
Removed final internal
papafe Jun 25, 2025
714c419
Improvements
papafe Jun 26, 2025
c796201
Small comments
papafe Jun 27, 2025
0f7cc7b
Some comments
papafe Jun 28, 2025
c56f972
Added getDiscriminatorInternal
papafe Jun 28, 2025
83ad951
Merged IBsonSerializationDomainInternal into IBsonSerializationDomain…
papafe Jun 28, 2025
34dce8a
Missing piece.
papafe Jun 28, 2025
7311b35
Fix for getDicriminatorConvention and IBsonIdProvider
papafe Jun 28, 2025
e9511c0
Big serializer check
papafe Jun 30, 2025
a783914
Fix for testing
papafe Jun 30, 2025
4c7d7ac
Added comment
papafe Jun 30, 2025
ee4410a
Small fix
papafe Jun 30, 2025
a31265a
Various fixes about RenderArgs plus new tests
papafe Jul 1, 2025
ef6d8bd
Small fix
papafe Jul 1, 2025
e7a703e
Simplified tests
papafe Jul 1, 2025
b86494b
Small fixes
papafe Jul 2, 2025
d32b3ac
Removed example builder and tests
papafe Jul 3, 2025
61ec09c
Various test fixes
papafe Jul 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 13 additions & 38 deletions src/MongoDB.Bson/BsonDefaults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,71 +24,46 @@ namespace MongoDB.Bson
/// </summary>
public static class BsonDefaults
{
// private static fields
private static bool __dynamicArraySerializerWasSet;
private static IBsonSerializer __dynamicArraySerializer;
private static bool __dynamicDocumentSerializerWasSet;
private static IBsonSerializer __dynamicDocumentSerializer;
private static int __maxDocumentSize = int.MaxValue;
private static int __maxSerializationDepth = 100;

// public static properties
/// <summary>
/// Gets or sets the dynamic array serializer.
/// </summary>
public static IBsonSerializer DynamicArraySerializer
{
get
{
if (!__dynamicArraySerializerWasSet)
{
__dynamicArraySerializer = BsonSerializer.LookupSerializer<List<object>>();
}
return __dynamicArraySerializer;
}
set
{
__dynamicArraySerializerWasSet = true;
__dynamicArraySerializer = value;
}
get => BsonSerializer.DefaultSerializationDomain.BsonDefaults.DynamicArraySerializer;
set => BsonSerializer.DefaultSerializationDomain.BsonDefaults.DynamicArraySerializer = value;
}

/// <summary>
/// Gets or sets the dynamic document serializer.
/// </summary>
public static IBsonSerializer DynamicDocumentSerializer
{
get
{
if (!__dynamicDocumentSerializerWasSet)
{
__dynamicDocumentSerializer = BsonSerializer.LookupSerializer<ExpandoObject>();
}
return __dynamicDocumentSerializer;
}
set
{
__dynamicDocumentSerializerWasSet = true;
__dynamicDocumentSerializer = value;
}
get => BsonSerializer.DefaultSerializationDomain.BsonDefaults.DynamicDocumentSerializer;
set => BsonSerializer.DefaultSerializationDomain.BsonDefaults.DynamicDocumentSerializer = value;
}

/* DOMAIN-API We should modify the API to have those two values (and in the writer/reader settings where they are used) be nullable.
* The problem is that we need to now when these values have been set externally or not. If they have not, then they should
* be retrieved from the closest domain.
*/

/// <summary>
/// Gets or sets the default max document size. The default is 4MiB.
/// </summary>
public static int MaxDocumentSize
{
get { return __maxDocumentSize; }
set { __maxDocumentSize = value; }
get => BsonSerializer.DefaultSerializationDomain.BsonDefaults.MaxDocumentSize;
set => BsonSerializer.DefaultSerializationDomain.BsonDefaults.MaxDocumentSize = value;
}

/// <summary>
/// Gets or sets the default max serialization depth (used to detect circular references during serialization). The default is 100.
/// </summary>
public static int MaxSerializationDepth
{
get { return __maxSerializationDepth; }
set { __maxSerializationDepth = value; }
get => BsonSerializer.DefaultSerializationDomain.BsonDefaults.MaxSerializationDepth;
set => BsonSerializer.DefaultSerializationDomain.BsonDefaults.MaxSerializationDepth = value;
}
}
}
73 changes: 73 additions & 0 deletions src/MongoDB.Bson/BsonDefaultsDomain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* Copyright 2010-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using System.Collections.Generic;
using System.Dynamic;
using MongoDB.Bson.Serialization;

namespace MongoDB.Bson
{
internal class BsonDefaultsDomain : IBsonDefaults
{
private IBsonSerializationDomain _serializationDomain;
private bool _dynamicArraySerializerWasSet;
private IBsonSerializer _dynamicArraySerializer;
private bool _dynamicDocumentSerializerWasSet;
private IBsonSerializer _dynamicDocumentSerializer;

public BsonDefaultsDomain(IBsonSerializationDomain serializationDomain)
{
_serializationDomain = serializationDomain;
}

public IBsonSerializer DynamicArraySerializer
{
get
{
if (!_dynamicArraySerializerWasSet)
{
_dynamicArraySerializer = _serializationDomain.LookupSerializer<List<object>>();
}
return _dynamicArraySerializer;
}
set
{
_dynamicArraySerializerWasSet = true;
_dynamicArraySerializer = value;
}
}

public IBsonSerializer DynamicDocumentSerializer
{
get
{
if (!_dynamicDocumentSerializerWasSet)
{
_dynamicDocumentSerializer = _serializationDomain.LookupSerializer<ExpandoObject>();
}
return _dynamicDocumentSerializer;
}
set
{
_dynamicDocumentSerializerWasSet = true;
_dynamicDocumentSerializer = value;
}
}

public int MaxDocumentSize { get; set; } = int.MaxValue;

public int MaxSerializationDepth { get; set; } = 100;
}
}
55 changes: 51 additions & 4 deletions src/MongoDB.Bson/BsonExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ namespace MongoDB.Bson
/// </summary>
public static class BsonExtensionMethods
{
//DOMAIN-API We should remove this and use the version with the domain.
//QUESTION: Do we want to do something now about this...? It's used also internally, but it seems in most cases it's used for "default serialization", so it should be ok.
/// <summary>
/// Serializes an object to a BSON byte array.
/// </summary>
Expand All @@ -49,6 +51,21 @@ public static byte[] ToBson<TNominalType>(
return ToBson(obj, typeof(TNominalType), writerSettings, serializer, configurator, args, estimatedBsonSize);
}

internal static byte[] ToBson<TNominalType>(
this TNominalType obj,
IBsonSerializationDomain serializationDomain,
IBsonSerializer<TNominalType> serializer = null,
BsonBinaryWriterSettings writerSettings = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default(BsonSerializationArgs),
int estimatedBsonSize = 0)
{
args.SetOrValidateNominalType(typeof(TNominalType), "<TNominalType>");

return ToBson(obj, typeof(TNominalType), serializationDomain, writerSettings, serializer, configurator, args, estimatedBsonSize);
}

//DOMAIN-API We should remove this and use the version with the domain.
/// <summary>
/// Serializes an object to a BSON byte array.
/// </summary>
Expand All @@ -68,6 +85,17 @@ public static byte[] ToBson(
BsonBinaryWriterSettings writerSettings = null,
IBsonSerializer serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default,
int estimatedBsonSize = 0) => ToBson(obj, nominalType, BsonSerializer.DefaultSerializationDomain, writerSettings,
serializer, configurator, args, estimatedBsonSize);

internal static byte[] ToBson(
this object obj,
Type nominalType,
IBsonSerializationDomain serializationDomain,
BsonBinaryWriterSettings writerSettings = null,
IBsonSerializer serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default(BsonSerializationArgs),
int estimatedBsonSize = 0)
{
Expand All @@ -84,7 +112,7 @@ public static byte[] ToBson(

if (serializer == null)
{
serializer = BsonSerializer.LookupSerializer(nominalType);
serializer = serializationDomain.LookupSerializer(nominalType);
}
if (serializer.ValueType != nominalType)
{
Expand Down Expand Up @@ -138,7 +166,16 @@ public static BsonDocument ToBsonDocument(
Type nominalType,
IBsonSerializer serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default(BsonSerializationArgs))
BsonSerializationArgs args = default) => ToBsonDocument(obj, nominalType,
BsonSerializer.DefaultSerializationDomain, serializer, configurator, args);

internal static BsonDocument ToBsonDocument(
this object obj,
Type nominalType,
IBsonSerializationDomain serializationDomain,
IBsonSerializer serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default)
{
if (nominalType == null)
{
Expand All @@ -165,7 +202,7 @@ public static BsonDocument ToBsonDocument(
return convertibleToBsonDocument.ToBsonDocument(); // use the provided ToBsonDocument method
}

serializer = BsonSerializer.LookupSerializer(nominalType);
serializer = serializationDomain.LookupSerializer(nominalType);
}
if (serializer.ValueType != nominalType)
{
Expand Down Expand Up @@ -226,6 +263,16 @@ public static string ToJson(
JsonWriterSettings writerSettings = null,
IBsonSerializer serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default)
=> ToJson(obj, nominalType, BsonSerializer.DefaultSerializationDomain, writerSettings, serializer, configurator, args);

internal static string ToJson(
this object obj,
Type nominalType,
IBsonSerializationDomain domain,
JsonWriterSettings writerSettings = null,
IBsonSerializer serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default(BsonSerializationArgs))
{
if (nominalType == null)
Expand All @@ -236,7 +283,7 @@ public static string ToJson(

if (serializer == null)
{
serializer = BsonSerializer.LookupSerializer(nominalType);
serializer = domain.LookupSerializer(nominalType);
}
if (serializer.ValueType != nominalType)
{
Expand Down
39 changes: 39 additions & 0 deletions src/MongoDB.Bson/IBsonDefaults.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* Copyright 2010-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using MongoDB.Bson.Serialization;

namespace MongoDB.Bson
{
internal interface IBsonDefaults
{
/// <summary>
///
/// </summary>
IBsonSerializer DynamicArraySerializer { get; set; }
/// <summary>
///
/// </summary>
IBsonSerializer DynamicDocumentSerializer { get; set; }
/// <summary>
///
/// </summary>
int MaxDocumentSize { get; set; }
/// <summary>
///
/// </summary>
int MaxSerializationDepth { get; set; }
}
}
3 changes: 2 additions & 1 deletion src/MongoDB.Bson/IO/BsonBinaryReaderSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ protected override BsonReaderSettings CloneImplementation()
Encoding = _encoding,
FixOldBinarySubTypeOnInput = _fixOldBinarySubTypeOnInput,
FixOldDateTimeMaxValueOnInput = _fixOldDateTimeMaxValueOnInput,
MaxDocumentSize = _maxDocumentSize
MaxDocumentSize = _maxDocumentSize,
SerializationDomain = SerializationDomain
};

return clone;
Expand Down
3 changes: 2 additions & 1 deletion src/MongoDB.Bson/IO/BsonBinaryWriterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ protected override BsonWriterSettings CloneImplementation()
Encoding = _encoding,
FixOldBinarySubTypeOnOutput = _fixOldBinarySubTypeOnOutput,
MaxDocumentSize = _maxDocumentSize,
MaxSerializationDepth = MaxSerializationDepth
MaxSerializationDepth = MaxSerializationDepth,
SerializationDomain = SerializationDomain,
};
return clone;
}
Expand Down
2 changes: 1 addition & 1 deletion src/MongoDB.Bson/IO/BsonDocumentReaderSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public static BsonDocumentReaderSettings Defaults
/// <returns>A clone of the settings.</returns>
protected override BsonReaderSettings CloneImplementation()
{
var clone = new BsonDocumentReaderSettings();
var clone = new BsonDocumentReaderSettings { SerializationDomain = SerializationDomain }; //TODO This can be improved
return clone;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/MongoDB.Bson/IO/BsonReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace MongoDB.Bson.IO
/// <summary>
/// Represents a BSON reader for some external format (see subclasses).
/// </summary>
public abstract class BsonReader : IBsonReader
public abstract class BsonReader : IBsonReaderInternal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IBsonReaderInternal not needed.

{
// private fields
private bool _disposed = false;
Expand Down
12 changes: 12 additions & 0 deletions src/MongoDB.Bson/IO/BsonReaderSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

using System;
using MongoDB.Bson.Serialization;

namespace MongoDB.Bson.IO
{
Expand All @@ -24,6 +25,7 @@ public abstract class BsonReaderSettings
{
// private fields
private bool _isFrozen;
private IBsonSerializationDomain _serializationDomain;

// constructors
/// <summary>
Expand Down Expand Up @@ -77,6 +79,16 @@ public BsonReaderSettings FrozenCopy()
}
}

internal IBsonSerializationDomain SerializationDomain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be a reader setting.

Classes in this directory are low level I/O classes that just do I/O.

Serialization is one level up and is built on TOP of these I/O classes.

{
get => _serializationDomain;
set
{
if (_isFrozen) { ThrowFrozenException(); }
_serializationDomain = value;
}
}

// protected methods
/// <summary>
/// Creates a clone of the settings.
Expand Down
Loading
Loading