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

Draft
wants to merge 31 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
945f07b
Rebase commit
papafe May 26, 2025
ebad2fe
Corrected type
papafe May 26, 2025
e2a6417
Various improvements, and added test for discriminators.
papafe May 26, 2025
1eae4f1
Removed comment.
papafe May 26, 2025
b842ea2
Small corrections.
papafe May 26, 2025
84d21de
Small correction.
papafe May 26, 2025
d6307e9
Corrected test
papafe May 26, 2025
ab0a9e1
Correction for test
papafe May 26, 2025
79bce23
Correction
papafe May 26, 2025
dec7221
Removed new tests untul refactoring
papafe May 26, 2025
a8b283f
Added domain to MongoQueryProvider
papafe May 27, 2025
e85acd6
Small fix
papafe May 27, 2025
c2b93bd
Corrected freeze
papafe May 27, 2025
308b475
Small correction
papafe May 27, 2025
3f15c39
Fixed BsonClassMap.Freeze and Convention Apply
papafe May 27, 2025
7800c5b
Small fix.
papafe Jun 4, 2025
13c1c89
Corrected test
papafe Jun 4, 2025
ab841cb
Made conventions internal
papafe Jun 4, 2025
4981af1
Corrected accessibility
papafe Jun 4, 2025
f289f3e
Fixed discriminator method
papafe Jun 12, 2025
ec1723c
Simplified
papafe Jun 12, 2025
2a0b2fd
Hide IBsonReader settings
papafe Jun 12, 2025
a5ec1eb
Other improvements
papafe Jun 12, 2025
a355fcd
Added constructor to avoid api compat issue
papafe Jun 13, 2025
388f2f9
Correct
papafe Jun 13, 2025
5f954c6
Small fixes
papafe Jun 13, 2025
84a0f21
Various fixes
papafe Jun 13, 2025
58f3080
Added BsonDefaults to domain
papafe Jun 16, 2025
1603128
Various fixes to hide API
papafe Jun 16, 2025
d302702
Small things
papafe Jun 17, 2025
48af503
Builders example
papafe Jun 17, 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
46 changes: 8 additions & 38 deletions src/MongoDB.Bson/BsonDefaults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,71 +24,41 @@ 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;
}

/// <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 //TODO This will need to be public at a later point
{
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;
}
}
77 changes: 73 additions & 4 deletions src/MongoDB.Bson/BsonExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,31 @@ 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);

/// <summary>
/// //TODO
/// </summary>
/// <param name="obj"></param>
/// <param name="nominalType"></param>
/// <param name="serializationDomain"></param>
/// <param name="writerSettings"></param>
/// <param name="serializer"></param>
/// <param name="configurator"></param>
/// <param name="args"></param>
/// <param name="estimatedBsonSize"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentNullException"></exception>
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 +109,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 +163,28 @@ 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);

/// <summary>
/// //TODO
/// </summary>
/// <param name="obj"></param>
/// <param name="nominalType"></param>
/// <param name="serializationDomain"></param>
/// <param name="serializer"></param>
/// <param name="configurator"></param>
/// <param name="args"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
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 +211,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 +272,29 @@ 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);

/// <summary>
/// //TODO
/// </summary>
/// <param name="obj"></param>
/// <param name="nominalType"></param>
/// <param name="domain"></param>
/// <param name="writerSettings"></param>
/// <param name="serializer"></param>
/// <param name="configurator"></param>
/// <param name="args"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public 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 +305,7 @@ public static string ToJson(

if (serializer == null)
{
serializer = BsonSerializer.LookupSerializer(nominalType);
serializer = domain.LookupSerializer(nominalType);
}
if (serializer.ValueType != nominalType)
{
Expand Down
88 changes: 88 additions & 0 deletions src/MongoDB.Bson/Builders/BuilderInterfaces.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/* 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;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions;

namespace MongoDB.Bson.Builders;

/* All the builders here contain the methods from the respective domain/classes that can be used for configurations.
*/

internal interface ISerializationDomainBuilder
{
ISerializationDomainBuilder RegisterDiscriminator(Type type, BsonValue discriminator);

ISerializationDomainBuilder RegisterDiscriminatorConvention(Type type, IDiscriminatorConvention convention);

ISerializationDomainBuilder RegisterGenericSerializerDefinition(
Type genericTypeDefinition,
Type genericSerializerDefinition);

ISerializationDomainBuilder RegisterIdGenerator(Type type, IIdGenerator idGenerator);

ISerializationDomainBuilder RegisterSerializationProvider(IBsonSerializationProvider provider);

ISerializationDomainBuilder RegisterSerializer<T>(IBsonSerializer<T> serializer);

ISerializationDomainBuilder RegisterSerializer(Type type, IBsonSerializer serializer);

ISerializationDomainBuilder TryRegisterSerializer(Type type, IBsonSerializer serializer);

ISerializationDomainBuilder TryRegisterSerializer<T>(IBsonSerializer<T> serializer);

ISerializationDomainBuilder UseNullIdChecker(bool useNullIdChecker);

ISerializationDomainBuilder UseZeroIdChecker(bool useZeroIdChecker);

ISerializationDomainBuilder ConfigureClassMap(Action<IBsonClassMapDomainBuilder> configure);

ISerializationDomainBuilder ConfigureConventionRegistry(Action<IConventionRegistryDomainBuilder> configure);

ISerializationDomainBuilder ConfigureBsonDefaults(Action<IBsonDefaultsBuilder> configure);

IBsonSerializationDomain1 Build();
}

internal interface IBsonClassMapDomainBuilder
{
IBsonClassMapDomainBuilder RegisterClassMap<TClass>();

IBsonClassMapDomainBuilder RegisterClassMap<TClass>(Action<BsonClassMap<TClass>> classMapInitializer);

IBsonClassMapDomainBuilder RegisterClassMap(BsonClassMap classMap);

IBsonClassMapDomainBuilder TryRegisterClassMap<TClass>();

IBsonClassMapDomainBuilder TryRegisterClassMap<TClass>(BsonClassMap<TClass> classMap);

IBsonClassMapDomainBuilder TryRegisterClassMap<TClass>(Action<BsonClassMap<TClass>> classMapInitializer);

IBsonClassMapDomainBuilder TryRegisterClassMap<TClass>(Func<BsonClassMap<TClass>> classMapFactory);
}

internal interface IConventionRegistryDomainBuilder
{
IConventionRegistryDomainBuilder Register(string name, IConventionPack conventions, Func<Type, bool> filter);
}

internal interface IBsonDefaultsBuilder
{
IBsonDefaultsBuilder SetDynamicArraySerializer(IBsonSerializer serializer);
IBsonDefaultsBuilder SetDynamicDocumentSerializer(IBsonSerializer serializer);
IBsonDefaultsBuilder SetMaxDocumentSize(int size);
IBsonDefaultsBuilder SetMaxSerializationDepth(int depth);
}
Loading