From 6422763221945217d3d78a8f99ad7780781785ed Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Tue, 6 May 2025 15:19:55 +0200 Subject: [PATCH 01/10] CSHARP-3494: Fix discriminator for generic types --- .../Serialization/BsonClassMap.cs | 20 ++++++- .../Jira/CSharp3494Tests.cs | 59 +++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs diff --git a/src/MongoDB.Bson/Serialization/BsonClassMap.cs b/src/MongoDB.Bson/Serialization/BsonClassMap.cs index 87239a33bf5..ace217ce4aa 100644 --- a/src/MongoDB.Bson/Serialization/BsonClassMap.cs +++ b/src/MongoDB.Bson/Serialization/BsonClassMap.cs @@ -1057,7 +1057,7 @@ public void Reset() _creatorMaps.Clear(); _creator = null; _declaredMemberMaps = new List(); - _discriminator = _classType.Name; + _discriminator = ComputeDiscriminator(); _discriminatorIsRequired = false; _extraElementsMemberMap = null; _idMemberMap = null; @@ -1067,6 +1067,24 @@ public void Reset() _knownTypes.Clear(); } + private string ComputeDiscriminator() + { + /* + * The discriminator is computed as follows: + * - if the class is non generic, that's just the name of the class + * - if the class is generic, then it's the AssemblyQualifiedName + */ + + if (_classType.IsGenericType) + { + return BsonUtils.GetFriendlyTypeName(_classType); //TODO We could just remove this method, keeping it in case I need to do something + } + else + { + return _classType.Name; + } + } + /// /// Sets the creator for the object. /// diff --git a/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs b/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs new file mode 100644 index 00000000000..74f42fab1bb --- /dev/null +++ b/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs @@ -0,0 +1,59 @@ +/* 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 FluentAssertions; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Driver.Tests.Linq.Linq3Implementation; +using Xunit; + +namespace MongoDB.Driver.Tests.Jira +{ + public class CSharp3494Tests : Linq3IntegrationTest + { + //[BsonKnownTypes(typeof(DerivedDocument), typeof(DerivedDocument))] + abstract class BaseDocument {} + + class DerivedDocument : BaseDocument + { + [BsonId] + public int Id { get; set; } + + public T Value { get; set; } + } + + [Fact] + public void Test1() + { + var doc1 = new DerivedDocument { Id = 1, Value = 42 }; + var serialized1 = doc1.ToJson(typeof(BaseDocument)); + + var baseCollection = GetCollection("AA","testBase"); + var untypedCollection = GetCollection("AA","testBase"); + + baseCollection.DeleteMany(FilterDefinition.Empty); + baseCollection.InsertOne(new DerivedDocument { Id = 1, Value = 42 }); + baseCollection.InsertOne(new DerivedDocument { Id = 2, Value = "42" }); + + var filter = Builders.Filter.Eq("_id", 1); + var filterInt = Builders.Filter.Eq("_id", 1); + + var untypedRetrievedDocument = untypedCollection.Find(filter).FirstOrDefault(); + var retrievedDocument = baseCollection.Find(filterInt).FirstOrDefault(); + + retrievedDocument.Should().NotBeNull(); + } + } +} \ No newline at end of file From 9570ae002ad4f210af33c8f50b0cbf0ec45a4256 Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Tue, 6 May 2025 15:38:22 +0200 Subject: [PATCH 02/10] Added tests --- .../Jira/CSharp3494Tests.cs | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs b/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs index 74f42fab1bb..cdabb0a52f1 100644 --- a/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs +++ b/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs @@ -15,6 +15,7 @@ using FluentAssertions; using MongoDB.Bson; +using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Driver.Tests.Linq.Linq3Implementation; using Xunit; @@ -23,8 +24,7 @@ namespace MongoDB.Driver.Tests.Jira { public class CSharp3494Tests : Linq3IntegrationTest { - //[BsonKnownTypes(typeof(DerivedDocument), typeof(DerivedDocument))] - abstract class BaseDocument {} + abstract class BaseDocument; class DerivedDocument : BaseDocument { @@ -35,25 +35,32 @@ class DerivedDocument : BaseDocument } [Fact] - public void Test1() + public void Correct_discriminator_should_be_used_for_generic_type() { - var doc1 = new DerivedDocument { Id = 1, Value = 42 }; - var serialized1 = doc1.ToJson(typeof(BaseDocument)); - - var baseCollection = GetCollection("AA","testBase"); - var untypedCollection = GetCollection("AA","testBase"); + var document = new DerivedDocument { Id = 1, Value = 42 }; + var serialized = document.ToJson(typeof(BaseDocument)); + serialized.Should().Be("""{ "_t" : "DerivedDocument", "_id" : 1, "Value" : 42 }"""); + } - baseCollection.DeleteMany(FilterDefinition.Empty); - baseCollection.InsertOne(new DerivedDocument { Id = 1, Value = 42 }); - baseCollection.InsertOne(new DerivedDocument { Id = 2, Value = "42" }); + [BsonKnownTypes(typeof(DerivedDocument2))] + abstract class BaseDocument2 {} - var filter = Builders.Filter.Eq("_id", 1); - var filterInt = Builders.Filter.Eq("_id", 1); + class DerivedDocument2 : BaseDocument2 + { + [BsonId] + public int Id { get; set; } - var untypedRetrievedDocument = untypedCollection.Find(filter).FirstOrDefault(); - var retrievedDocument = baseCollection.Find(filterInt).FirstOrDefault(); + public T Value { get; set; } + } - retrievedDocument.Should().NotBeNull(); + [Fact] + public void Test2() + { + //This test needs to use a different set of classes than the previous one, otherwise the discriminators could have been already + //registered, depending on the order of the tests. We need BsonKnownTypes for this to work. + var serialized = """{ "_t" : "DerivedDocument2", "_id" : 1, "Value" : 42 }"""; + var rehydrated = BsonSerializer.Deserialize(serialized); + rehydrated.Should().BeOfType>(); } } } \ No newline at end of file From 35fb461c7d1bcab46044e9764e06962ca55914ea Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Tue, 6 May 2025 15:40:13 +0200 Subject: [PATCH 03/10] Simplification --- .../Serialization/BsonClassMap.cs | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/MongoDB.Bson/Serialization/BsonClassMap.cs b/src/MongoDB.Bson/Serialization/BsonClassMap.cs index ace217ce4aa..e7410ef9031 100644 --- a/src/MongoDB.Bson/Serialization/BsonClassMap.cs +++ b/src/MongoDB.Bson/Serialization/BsonClassMap.cs @@ -1057,7 +1057,7 @@ public void Reset() _creatorMaps.Clear(); _creator = null; _declaredMemberMaps = new List(); - _discriminator = ComputeDiscriminator(); + _discriminator = BsonUtils.GetFriendlyTypeName(_classType); _discriminatorIsRequired = false; _extraElementsMemberMap = null; _idMemberMap = null; @@ -1067,24 +1067,6 @@ public void Reset() _knownTypes.Clear(); } - private string ComputeDiscriminator() - { - /* - * The discriminator is computed as follows: - * - if the class is non generic, that's just the name of the class - * - if the class is generic, then it's the AssemblyQualifiedName - */ - - if (_classType.IsGenericType) - { - return BsonUtils.GetFriendlyTypeName(_classType); //TODO We could just remove this method, keeping it in case I need to do something - } - else - { - return _classType.Name; - } - } - /// /// Sets the creator for the object. /// From 2132420954862d02897f8be0010de9aadd038ef9 Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Tue, 6 May 2025 16:07:32 +0200 Subject: [PATCH 04/10] Name correction --- tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs b/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs index cdabb0a52f1..57b3dd6de98 100644 --- a/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs +++ b/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs @@ -54,7 +54,7 @@ class DerivedDocument2 : BaseDocument2 } [Fact] - public void Test2() + public void Correct_type_should_be_instantiated_with_discriminator_for_generic_type() { //This test needs to use a different set of classes than the previous one, otherwise the discriminators could have been already //registered, depending on the order of the tests. We need BsonKnownTypes for this to work. From bb4795e2d3b4ba92f378aaa313be4b6ea95f9d92 Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Fri, 23 May 2025 11:03:30 +0200 Subject: [PATCH 05/10] Fixed test --- tests/MongoDB.Bson.Tests/Jira/CSharp515Tests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/MongoDB.Bson.Tests/Jira/CSharp515Tests.cs b/tests/MongoDB.Bson.Tests/Jira/CSharp515Tests.cs index 27de1f7abaa..04350931f01 100644 --- a/tests/MongoDB.Bson.Tests/Jira/CSharp515Tests.cs +++ b/tests/MongoDB.Bson.Tests/Jira/CSharp515Tests.cs @@ -45,7 +45,7 @@ public S(IList list) } private static readonly string __discriminatorAssemblyName = "MongoDB.Bson.Tests"; - private string _jsonTemplate = ("{ '_id' : 1, 'R' : #V, 'S' : #V, 'RS' : { '_t' : 'S`1', '_v' : #V }, 'OR' : { '_t' : 'System.Collections.ObjectModel.ReadOnlyCollection`1[System.Int32]', '_v' : #V }, 'OS' : { '_t' : 'MongoDB.Bson.Tests.Jira.CSharp515.CSharp515Tests+S`1[System.Int32], " + __discriminatorAssemblyName + "', '_v' : #V } }").Replace("'", "\""); + private string _jsonTemplate = ("{ '_id' : 1, 'R' : #V, 'S' : #V, 'RS' : { '_t' : 'S', '_v' : #V }, 'OR' : { '_t' : 'System.Collections.ObjectModel.ReadOnlyCollection`1[System.Int32]', '_v' : #V }, 'OS' : { '_t' : 'MongoDB.Bson.Tests.Jira.CSharp515.CSharp515Tests+S`1[System.Int32], " + __discriminatorAssemblyName + "', '_v' : #V } }").Replace("'", "\""); [Fact] public void TestNull() From 20c01e21bd0144c7ca4d996e8dd177b0e04b84e7 Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Fri, 23 May 2025 12:08:55 +0200 Subject: [PATCH 06/10] Improved testing --- .../Jira/CSharp3494Tests.cs | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs b/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs index 57b3dd6de98..014eeda57dc 100644 --- a/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs +++ b/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs @@ -13,6 +13,7 @@ * limitations under the License. */ +using System.Collections.Generic; using FluentAssertions; using MongoDB.Bson; using MongoDB.Bson.Serialization; @@ -34,6 +35,16 @@ class DerivedDocument : BaseDocument public T Value { get; set; } } + class DerivedDocumentDouble : BaseDocument + { + [BsonId] + public int Id { get; set; } + + public T1 Value1 { get; set; } + + public T2 Value2 { get; set; } + } + [Fact] public void Correct_discriminator_should_be_used_for_generic_type() { @@ -42,7 +53,25 @@ public void Correct_discriminator_should_be_used_for_generic_type() serialized.Should().Be("""{ "_t" : "DerivedDocument", "_id" : 1, "Value" : 42 }"""); } + [Fact] + public void Correct_discriminator_should_be_used_for_generic_type_with_nested_type() + { + var document = new DerivedDocument>> { Id = 1, Value = [new() { { "key", 1 } }] }; + var serialized = document.ToJson(typeof(BaseDocument)); + serialized.Should().Be("""{ "_t" : "DerivedDocument>>", "_id" : 1, "Value" : [{ "key" : 1 }] }"""); + } + + [Fact] + public void Correct_discriminator_should_be_used_for_generic_type_with_two_types() + { + var document = new DerivedDocumentDouble { Id = 1, Value1 = 42, Value2 = "hello"}; + var serialized = document.ToJson(typeof(BaseDocument)); + serialized.Should().Be("""{ "_t" : "DerivedDocumentDouble", "_id" : 1, "Value1" : 42, "Value2" : "hello" }"""); + } + [BsonKnownTypes(typeof(DerivedDocument2))] + [BsonKnownTypes(typeof(DerivedDocument2>>))] + [BsonKnownTypes(typeof(DerivedDocumentDouble2))] abstract class BaseDocument2 {} class DerivedDocument2 : BaseDocument2 @@ -53,14 +82,42 @@ class DerivedDocument2 : BaseDocument2 public T Value { get; set; } } + class DerivedDocumentDouble2 : BaseDocument2 + { + [BsonId] + public int Id { get; set; } + + public T1 Value1 { get; set; } + + public T2 Value2 { get; set; } + } + + //The following tests needs to use a different set of classes than the previous one, otherwise the discriminators could have been already + //registered, depending on the order of the tests. + //It's necessary to specify the derived specific types with BsonKnownTypes for this to work. + [Fact] public void Correct_type_should_be_instantiated_with_discriminator_for_generic_type() { - //This test needs to use a different set of classes than the previous one, otherwise the discriminators could have been already - //registered, depending on the order of the tests. We need BsonKnownTypes for this to work. var serialized = """{ "_t" : "DerivedDocument2", "_id" : 1, "Value" : 42 }"""; var rehydrated = BsonSerializer.Deserialize(serialized); rehydrated.Should().BeOfType>(); } + + [Fact] + public void Correct_type_should_be_instantiated_with_discriminator_for_generic_type_with_nested_type() + { + var serialized = """{ "_t" : "DerivedDocument2>>", "_id" : 1, "Value" : [{ "key" : 1 }] }"""; + var rehydrated = BsonSerializer.Deserialize(serialized); + rehydrated.Should().BeOfType>>>(); + } + + [Fact] + public void Correct_type_should_be_instantiated_with_discriminator_for_generic_type_with_two_types() + { + var serialized = """{ "_t" : "DerivedDocumentDouble2", "_id" : 1, "Value1" : 42, "Value2" : "hello" }"""; + var rehydrated = BsonSerializer.Deserialize(serialized); + rehydrated.Should().BeOfType>(); + } } } \ No newline at end of file From cf10e779017d494157f671c5f8eabc5edd3c91f4 Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Fri, 23 May 2025 12:20:35 +0200 Subject: [PATCH 07/10] Moved tests. --- .../Serializers/DiscriminatorTests.cs | 96 ++++++++++++++ .../Jira/CSharp3494Tests.cs | 123 ------------------ 2 files changed, 96 insertions(+), 123 deletions(-) delete mode 100644 tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs diff --git a/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs b/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs index 78fe458a3aa..2057159ebbc 100644 --- a/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs +++ b/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs @@ -13,7 +13,9 @@ * limitations under the License. */ +using System.Collections.Generic; using System.Linq; +using FluentAssertions; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.TestHelpers; @@ -65,6 +67,100 @@ private class H : G { } + abstract class BaseDocument; + + class DerivedDocument : BaseDocument + { + [BsonId] + public int Id { get; set; } + + public T Value { get; set; } + } + + class DerivedDocumentDouble : BaseDocument + { + [BsonId] + public int Id { get; set; } + + public T1 Value1 { get; set; } + + public T2 Value2 { get; set; } + } + + //The deserialization tests for generic types needs to use a different set of classes than the serialization ones, + //otherwise the discriminators could have been already registered, depending on the order of the tests. + //It's necessary to specify the derived specific types with BsonKnownTypes for this to work. + [BsonKnownTypes(typeof(DerivedDocument2))] + [BsonKnownTypes(typeof(DerivedDocument2>>))] + [BsonKnownTypes(typeof(DerivedDocumentDouble2))] + abstract class BaseDocument2 {} + + class DerivedDocument2 : BaseDocument2 + { + [BsonId] + public int Id { get; set; } + + public T Value { get; set; } + } + + class DerivedDocumentDouble2 : BaseDocument2 + { + [BsonId] + public int Id { get; set; } + + public T1 Value1 { get; set; } + + public T2 Value2 { get; set; } + } + + [Fact] + public void TestDeserializeGenericType() + { + var serialized = """{ "_t" : "DerivedDocument2", "_id" : 1, "Value" : 42 }"""; + var rehydrated = BsonSerializer.Deserialize(serialized); + rehydrated.Should().BeOfType>(); + } + + [Fact] + public void TestDeserializeGenericTypeWithNestedType() + { + var serialized = """{ "_t" : "DerivedDocument2>>", "_id" : 1, "Value" : [{ "key" : 1 }] }"""; + var rehydrated = BsonSerializer.Deserialize(serialized); + rehydrated.Should().BeOfType>>>(); + } + + [Fact] + public void TestDeserializeGenericTypeWithTwoTypes() + { + var serialized = """{ "_t" : "DerivedDocumentDouble2", "_id" : 1, "Value1" : 42, "Value2" : "hello" }"""; + var rehydrated = BsonSerializer.Deserialize(serialized); + rehydrated.Should().BeOfType>(); + } + + [Fact] + public void TestSerializeGenericType() + { + var document = new DerivedDocument { Id = 1, Value = 42 }; + var serialized = document.ToJson(typeof(BaseDocument)); + serialized.Should().Be("""{ "_t" : "DerivedDocument", "_id" : 1, "Value" : 42 }"""); + } + + [Fact] + public void TestSerializeGenericTypeWithNestedType() + { + var document = new DerivedDocument>> { Id = 1, Value = [new() { { "key", 1 } }] }; + var serialized = document.ToJson(typeof(BaseDocument)); + serialized.Should().Be("""{ "_t" : "DerivedDocument>>", "_id" : 1, "Value" : [{ "key" : 1 }] }"""); + } + + [Fact] + public void TestSerializeGenericTypeWithTwoTypes() + { + var document = new DerivedDocumentDouble { Id = 1, Value1 = 42, Value2 = "hello"}; + var serialized = document.ToJson(typeof(BaseDocument)); + serialized.Should().Be("""{ "_t" : "DerivedDocumentDouble", "_id" : 1, "Value1" : 42, "Value2" : "hello" }"""); + } + [Fact] public void TestSerializeObjectasObject() { diff --git a/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs b/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs deleted file mode 100644 index 014eeda57dc..00000000000 --- a/tests/MongoDB.Driver.Tests/Jira/CSharp3494Tests.cs +++ /dev/null @@ -1,123 +0,0 @@ -/* 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 FluentAssertions; -using MongoDB.Bson; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Attributes; -using MongoDB.Driver.Tests.Linq.Linq3Implementation; -using Xunit; - -namespace MongoDB.Driver.Tests.Jira -{ - public class CSharp3494Tests : Linq3IntegrationTest - { - abstract class BaseDocument; - - class DerivedDocument : BaseDocument - { - [BsonId] - public int Id { get; set; } - - public T Value { get; set; } - } - - class DerivedDocumentDouble : BaseDocument - { - [BsonId] - public int Id { get; set; } - - public T1 Value1 { get; set; } - - public T2 Value2 { get; set; } - } - - [Fact] - public void Correct_discriminator_should_be_used_for_generic_type() - { - var document = new DerivedDocument { Id = 1, Value = 42 }; - var serialized = document.ToJson(typeof(BaseDocument)); - serialized.Should().Be("""{ "_t" : "DerivedDocument", "_id" : 1, "Value" : 42 }"""); - } - - [Fact] - public void Correct_discriminator_should_be_used_for_generic_type_with_nested_type() - { - var document = new DerivedDocument>> { Id = 1, Value = [new() { { "key", 1 } }] }; - var serialized = document.ToJson(typeof(BaseDocument)); - serialized.Should().Be("""{ "_t" : "DerivedDocument>>", "_id" : 1, "Value" : [{ "key" : 1 }] }"""); - } - - [Fact] - public void Correct_discriminator_should_be_used_for_generic_type_with_two_types() - { - var document = new DerivedDocumentDouble { Id = 1, Value1 = 42, Value2 = "hello"}; - var serialized = document.ToJson(typeof(BaseDocument)); - serialized.Should().Be("""{ "_t" : "DerivedDocumentDouble", "_id" : 1, "Value1" : 42, "Value2" : "hello" }"""); - } - - [BsonKnownTypes(typeof(DerivedDocument2))] - [BsonKnownTypes(typeof(DerivedDocument2>>))] - [BsonKnownTypes(typeof(DerivedDocumentDouble2))] - abstract class BaseDocument2 {} - - class DerivedDocument2 : BaseDocument2 - { - [BsonId] - public int Id { get; set; } - - public T Value { get; set; } - } - - class DerivedDocumentDouble2 : BaseDocument2 - { - [BsonId] - public int Id { get; set; } - - public T1 Value1 { get; set; } - - public T2 Value2 { get; set; } - } - - //The following tests needs to use a different set of classes than the previous one, otherwise the discriminators could have been already - //registered, depending on the order of the tests. - //It's necessary to specify the derived specific types with BsonKnownTypes for this to work. - - [Fact] - public void Correct_type_should_be_instantiated_with_discriminator_for_generic_type() - { - var serialized = """{ "_t" : "DerivedDocument2", "_id" : 1, "Value" : 42 }"""; - var rehydrated = BsonSerializer.Deserialize(serialized); - rehydrated.Should().BeOfType>(); - } - - [Fact] - public void Correct_type_should_be_instantiated_with_discriminator_for_generic_type_with_nested_type() - { - var serialized = """{ "_t" : "DerivedDocument2>>", "_id" : 1, "Value" : [{ "key" : 1 }] }"""; - var rehydrated = BsonSerializer.Deserialize(serialized); - rehydrated.Should().BeOfType>>>(); - } - - [Fact] - public void Correct_type_should_be_instantiated_with_discriminator_for_generic_type_with_two_types() - { - var serialized = """{ "_t" : "DerivedDocumentDouble2", "_id" : 1, "Value1" : 42, "Value2" : "hello" }"""; - var rehydrated = BsonSerializer.Deserialize(serialized); - rehydrated.Should().BeOfType>(); - } - } -} \ No newline at end of file From bbe4516958f4ca1e682e23a345dd90cba007d309 Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Fri, 23 May 2025 12:23:12 +0200 Subject: [PATCH 08/10] Added comment. --- .../Serialization/Serializers/DiscriminatorTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs b/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs index 2057159ebbc..7d823b2b30b 100644 --- a/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs +++ b/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs @@ -67,6 +67,7 @@ private class H : G { } + // BaseDocument, BasedDocument2 and derived classes are used for tests with generic types abstract class BaseDocument; class DerivedDocument : BaseDocument From 6446d0afbec757d2bfbaf0649bb988c91048ff29 Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Tue, 3 Jun 2025 17:32:48 +0200 Subject: [PATCH 09/10] Small fix. --- .../Serializers/DiscriminatorTests.cs | 50 ++++++------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs b/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs index 7d823b2b30b..071e768c61b 100644 --- a/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs +++ b/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs @@ -67,7 +67,11 @@ private class H : G { } - // BaseDocument, BasedDocument2 and derived classes are used for tests with generic types + // BaseDocument, BasedDocument and derived classes are used for tests with generic types + // It's necessary to specify the derived specific types with BsonKnownTypes for the deserialization to work. + [BsonKnownTypes(typeof(DerivedDocument))] + [BsonKnownTypes(typeof(DerivedDocument>>))] + [BsonKnownTypes(typeof(DerivedDocumentDouble))] abstract class BaseDocument; class DerivedDocument : BaseDocument @@ -88,54 +92,28 @@ class DerivedDocumentDouble : BaseDocument public T2 Value2 { get; set; } } - //The deserialization tests for generic types needs to use a different set of classes than the serialization ones, - //otherwise the discriminators could have been already registered, depending on the order of the tests. - //It's necessary to specify the derived specific types with BsonKnownTypes for this to work. - [BsonKnownTypes(typeof(DerivedDocument2))] - [BsonKnownTypes(typeof(DerivedDocument2>>))] - [BsonKnownTypes(typeof(DerivedDocumentDouble2))] - abstract class BaseDocument2 {} - - class DerivedDocument2 : BaseDocument2 - { - [BsonId] - public int Id { get; set; } - - public T Value { get; set; } - } - - class DerivedDocumentDouble2 : BaseDocument2 - { - [BsonId] - public int Id { get; set; } - - public T1 Value1 { get; set; } - - public T2 Value2 { get; set; } - } - [Fact] public void TestDeserializeGenericType() { - var serialized = """{ "_t" : "DerivedDocument2", "_id" : 1, "Value" : 42 }"""; - var rehydrated = BsonSerializer.Deserialize(serialized); - rehydrated.Should().BeOfType>(); + var serialized = """{ "_t" : "DerivedDocument", "_id" : 1, "Value" : 42 }"""; + var rehydrated = BsonSerializer.Deserialize(serialized); + rehydrated.Should().BeOfType>(); } [Fact] public void TestDeserializeGenericTypeWithNestedType() { - var serialized = """{ "_t" : "DerivedDocument2>>", "_id" : 1, "Value" : [{ "key" : 1 }] }"""; - var rehydrated = BsonSerializer.Deserialize(serialized); - rehydrated.Should().BeOfType>>>(); + var serialized = """{ "_t" : "DerivedDocument>>", "_id" : 1, "Value" : [{ "key" : 1 }] }"""; + var rehydrated = BsonSerializer.Deserialize(serialized); + rehydrated.Should().BeOfType>>>(); } [Fact] public void TestDeserializeGenericTypeWithTwoTypes() { - var serialized = """{ "_t" : "DerivedDocumentDouble2", "_id" : 1, "Value1" : 42, "Value2" : "hello" }"""; - var rehydrated = BsonSerializer.Deserialize(serialized); - rehydrated.Should().BeOfType>(); + var serialized = """{ "_t" : "DerivedDocumentDouble", "_id" : 1, "Value1" : 42, "Value2" : "hello" }"""; + var rehydrated = BsonSerializer.Deserialize(serialized); + rehydrated.Should().BeOfType>(); } [Fact] From 32d3a3ed0109283dab69b15b120323d8f67aa4bc Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Tue, 10 Jun 2025 19:17:33 +0200 Subject: [PATCH 10/10] Update tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs --- .../Serialization/Serializers/DiscriminatorTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs b/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs index 071e768c61b..def1a5e027b 100644 --- a/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs +++ b/tests/MongoDB.Bson.Tests/Serialization/Serializers/DiscriminatorTests.cs @@ -67,7 +67,7 @@ private class H : G { } - // BaseDocument, BasedDocument and derived classes are used for tests with generic types + // BaseDocument and derived classes are used for tests with generic types // It's necessary to specify the derived specific types with BsonKnownTypes for the deserialization to work. [BsonKnownTypes(typeof(DerivedDocument))] [BsonKnownTypes(typeof(DerivedDocument>>))]