Skip to content

Commit e6b8b35

Browse files
committed
Fixed BsonClassMap.Freeze and Convention Apply
1 parent 5e6931c commit e6b8b35

File tree

5 files changed

+68
-11
lines changed

5 files changed

+68
-11
lines changed

src/MongoDB.Bson/ObjectModel/BsonDocumentWrapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public static BsonDocumentWrapper Create(Type nominalType, object value) =>
124124
/// <returns></returns>
125125
public static BsonDocumentWrapper Create(Type nominalType, object value, IBsonSerializationDomain domain)
126126
{
127-
var serializer = domain.LookupSerializer(nominalType); //TODO ??
127+
var serializer = domain.LookupSerializer(nominalType);
128128
return new BsonDocumentWrapper(value, serializer);
129129
}
130130

src/MongoDB.Bson/Serialization/BsonClassMap.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ internal BsonClassMap Freeze(IBsonSerializationDomainInternal domain)
420420
return Freeze(freezeContext);
421421
}
422422

423-
private BsonClassMap Freeze(FreezeContext context) //TODO This is not completely correct, because LookupClassMap calls freeze
423+
private BsonClassMap Freeze(FreezeContext context)
424424
{
425425
var configLock = context.SerializationDomain!.ConfigLock;
426426
configLock.EnterReadLock();
@@ -451,7 +451,7 @@ private BsonClassMap Freeze(FreezeContext context) //TODO This is not completel
451451
{
452452
_baseClassMap = context.SerializationDomain.BsonClassMap.LookupClassMap(baseType);
453453
}
454-
_baseClassMap.Freeze(context); //TODO This is not necessary, because LookupClassMap will only return a frozen class map
454+
_baseClassMap.Freeze(context);
455455
_discriminatorIsRequired |= _baseClassMap._discriminatorIsRequired;
456456
_hasRootClass |= (_isRootClass || _baseClassMap.HasRootClass);
457457
_allMemberMaps.AddRange(_baseClassMap.AllMemberMaps);
@@ -1229,7 +1229,7 @@ internal IDiscriminatorConvention GetDiscriminatorConvention()
12291229
private void AutoMapClass(IBsonSerializationDomain serializationDomain)
12301230
{
12311231
var conventionPack = serializationDomain.ConventionRegistry.Lookup(_classType);
1232-
new ConventionRunner(conventionPack).Apply(this);
1232+
new ConventionRunner(conventionPack).Apply(this, serializationDomain);
12331233

12341234
foreach (var memberMap in _declaredMemberMaps)
12351235
{

src/MongoDB.Bson/Serialization/Conventions/ConventionRunner.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ public ConventionRunner(IConventionPack conventions)
4747
/// Applies a modification to the class map.
4848
/// </summary>
4949
/// <param name="classMap">The class map.</param>
50-
public void Apply(BsonClassMap classMap)
50+
public void Apply(BsonClassMap classMap) => Apply(classMap, BsonSerializer.DefaultSerializationDomain);
51+
52+
internal void Apply(BsonClassMap classMap, IBsonSerializationDomain serializationDomain)
5153
{
5254
foreach (var convention in _conventions.OfType<IClassMapConvention>())
5355
{
@@ -58,7 +60,7 @@ public void Apply(BsonClassMap classMap)
5860
{
5961
foreach (var memberMap in classMap.DeclaredMemberMaps)
6062
{
61-
convention.Apply(memberMap);
63+
convention.Apply(memberMap, serializationDomain);
6264
}
6365
}
6466

@@ -72,7 +74,7 @@ public void Apply(BsonClassMap classMap)
7274

7375
foreach (var convention in _conventions.OfType<IPostProcessingConvention>())
7476
{
75-
convention.PostProcess(classMap);
77+
convention.PostProcess(classMap, serializationDomain);
7678
}
7779
}
7880
}

src/MongoDB.Bson/Serialization/Serializers/DiscriminatedInterfaceSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ private static IBsonSerializer<TInterface> CreateInterfaceSerializer(IBsonSerial
4848
var classMap = (BsonClassMap)Activator.CreateInstance(classMapType);
4949
classMap.AutoMap();
5050
classMap.SetDiscriminatorConvention(serializationDomain.LookupDiscriminatorConvention(typeof(TInterface)));
51-
classMap.Freeze();
51+
classMap.Freeze(serializationDomain as IBsonSerializationDomainInternal);
5252
return new BsonClassMapSerializer<TInterface>(classMap);
5353
}
5454
#endregion

tests/MongoDB.Driver.Tests/MultipleRegistriesTests.cs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,20 @@
1717
using MongoDB.Bson;
1818
using MongoDB.Bson.Serialization;
1919
using MongoDB.Bson.Serialization.Attributes;
20+
using MongoDB.Bson.Serialization.Conventions;
2021
using MongoDB.Bson.Serialization.Serializers;
22+
using MongoDB.Driver.Core.TestHelpers.XunitExtensions;
2123
using Xunit;
2224

2325
namespace MongoDB.Driver.Tests
2426
{
2527
public class MultipleRegistriesTests
2628
{
27-
//[Fact]
29+
[Fact]
2830
public void TestSerialization()
2931
{
32+
RequireServer.Check();
33+
3034
{
3135
var client = DriverTestConfiguration.CreateMongoClient();
3236
var db = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
@@ -73,9 +77,11 @@ public void TestSerialization()
7377
}
7478
}
7579

76-
//[Fact]
80+
[Fact]
7781
public void TestDeserialization()
7882
{
83+
RequireServer.Check();
84+
7985
{
8086
var client = DriverTestConfiguration.CreateMongoClient();
8187
var db = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
@@ -99,9 +105,11 @@ public void TestDeserialization()
99105
}
100106
}
101107

102-
//[Fact]
108+
[Fact]
103109
public void TestLinq()
104110
{
111+
RequireServer.Check();
112+
105113
var customDomain = BsonSerializer.CreateSerializationDomain();
106114
customDomain.RegisterSerializer(new CustomStringSerializer());
107115

@@ -125,6 +133,40 @@ public void TestLinq()
125133
Assert.NotEmpty(retrievedTyped);
126134
}
127135

136+
[Fact]
137+
public void TestConventions()
138+
{
139+
RequireServer.Check();
140+
141+
var customDomain = BsonSerializer.CreateSerializationDomain();
142+
143+
// Register an id generator convention that uses a custom ObjectIdGenerator
144+
customDomain.RegisterIdGenerator(typeof(ObjectId), new CustomObjectIdGenerator());
145+
146+
//Register a convention to use lowercase for all fields on the Person class
147+
var pack = new ConventionPack();
148+
pack.AddMemberMapConvention(
149+
"LowerCaseElementName",
150+
m => m.SetElementName(m.MemberName.ToLower()));
151+
customDomain.ConventionRegistry.Register("myPack", pack, t => t == typeof(Person));
152+
153+
var client = DriverTestConfiguration.CreateMongoClient(c => c.SerializationDomain = customDomain);
154+
var db = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
155+
db.DropCollection(DriverTestConfiguration.CollectionNamespace.CollectionName);
156+
var collection = db.GetCollection<Person>(DriverTestConfiguration.CollectionNamespace.CollectionName);
157+
var untypedCollection = db.GetCollection<BsonDocument>(DriverTestConfiguration.CollectionNamespace.CollectionName);
158+
159+
var person = new Person { Name = "Mario", Age = 24 }; //Id is not set, so the custom ObjectIdGenerator should be used
160+
collection.InsertOne(person);
161+
162+
var retrievedAsBson = untypedCollection.FindSync("{}").ToList().Single();
163+
var toString = retrievedAsBson.ToString();
164+
165+
var expectedVal =
166+
"""{ "_id" : { "$oid" : "6797b56bf5495bf53aa3078f" }, "name" : "Mario", "age" : 24 }""";
167+
Assert.Equal(expectedVal, toString);
168+
}
169+
128170
public class Person
129171
{
130172
[BsonId] public ObjectId Id { get; set; }
@@ -174,5 +216,18 @@ protected override void SerializeValue(BsonSerializationContext context, BsonSer
174216
bsonWriter.WriteString(value + "test");
175217
}
176218
}
219+
220+
public class CustomObjectIdGenerator : IIdGenerator
221+
{
222+
public object GenerateId(object container, object document)
223+
{
224+
return ObjectId.Parse("6797b56bf5495bf53aa3078f");
225+
}
226+
227+
public bool IsEmpty(object id)
228+
{
229+
return true;
230+
}
231+
}
177232
}
178233
}

0 commit comments

Comments
 (0)