From bb80a336b32b26a47c06f3d620d69b221e93c831 Mon Sep 17 00:00:00 2001 From: Matthias Gernand Date: Fri, 3 Jun 2022 13:05:04 +0200 Subject: [PATCH] Extended the MongoDB serializer support. (#5) Extended the MongoDB serializer support with the configuration of the representation type. --- .../ConventionPackExtensions.cs | 9 ++++- .../StronglyTypedIdConvention.cs | 38 ++++++++++++++++++- .../StronglyTypedIdSerializer.cs | 32 +++++++++++++++- .../IStronglyTypedId.cs | 2 +- .../ConverterTests.cs | 6 +-- 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/src/Fluxera.StronglyTypedId.MongoDB/ConventionPackExtensions.cs b/src/Fluxera.StronglyTypedId.MongoDB/ConventionPackExtensions.cs index 6f96a7c..145f898 100644 --- a/src/Fluxera.StronglyTypedId.MongoDB/ConventionPackExtensions.cs +++ b/src/Fluxera.StronglyTypedId.MongoDB/ConventionPackExtensions.cs @@ -1,5 +1,6 @@ namespace Fluxera.StronglyTypedId.MongoDB { + using global::MongoDB.Bson; using global::MongoDB.Bson.Serialization.Conventions; using JetBrains.Annotations; @@ -13,10 +14,14 @@ public static class ConventionPackExtensions /// Configure the serializer to use the . /// /// + /// + /// /// - public static ConventionPack UseStronglyTypedId(this ConventionPack pack) + public static ConventionPack UseStronglyTypedId(this ConventionPack pack, + BsonType stringRepresentation = BsonType.ObjectId, + GuidRepresentation guidRepresentation = GuidRepresentation.Standard) { - pack.Add(new StronglyTypedIdConvention()); + pack.Add(new StronglyTypedIdConvention(stringRepresentation, guidRepresentation)); return pack; } diff --git a/src/Fluxera.StronglyTypedId.MongoDB/StronglyTypedIdConvention.cs b/src/Fluxera.StronglyTypedId.MongoDB/StronglyTypedIdConvention.cs index 679c476..5e0e4ae 100644 --- a/src/Fluxera.StronglyTypedId.MongoDB/StronglyTypedIdConvention.cs +++ b/src/Fluxera.StronglyTypedId.MongoDB/StronglyTypedIdConvention.cs @@ -1,8 +1,11 @@ namespace Fluxera.StronglyTypedId.MongoDB { using System; + using Fluxera.Utilities.Extensions; + using global::MongoDB.Bson; using global::MongoDB.Bson.Serialization; using global::MongoDB.Bson.Serialization.Conventions; + using global::MongoDB.Bson.Serialization.Serializers; using JetBrains.Annotations; /// @@ -11,11 +14,27 @@ [PublicAPI] public sealed class StronglyTypedIdConvention : ConventionBase, IMemberMapConvention { + private readonly IBsonSerializer guidSerializer; + private readonly IBsonSerializer stringSerializer; + + /// + /// Initializes a new instance of the type. + /// + /// + /// + public StronglyTypedIdConvention( + BsonType stringRepresentation = BsonType.ObjectId, + GuidRepresentation guidRepresentation = GuidRepresentation.Standard) + { + this.stringSerializer = new StringSerializer(stringRepresentation); + this.guidSerializer = new GuidSerializer(guidRepresentation); + } + /// public void Apply(BsonMemberMap memberMap) { Type originalMemberType = memberMap.MemberType; - Type memberType = Nullable.GetUnderlyingType(originalMemberType) ?? originalMemberType; + Type memberType = originalMemberType.UnwrapNullableType(); if(memberType.IsStronglyTypedId()) { @@ -23,7 +42,22 @@ public void Apply(BsonMemberMap memberMap) Type serializerTypeTemplate = typeof(StronglyTypedIdSerializer<,>); Type serializerType = serializerTypeTemplate.MakeGenericType(memberType, valueType); - IBsonSerializer enumerationSerializer = (IBsonSerializer)Activator.CreateInstance(serializerType); + IBsonSerializer serializer; + + if(valueType == typeof(string)) + { + serializer = this.stringSerializer; + } + else if(valueType == typeof(Guid)) + { + serializer = this.guidSerializer; + } + else + { + serializer = BsonSerializer.LookupSerializer(valueType); + } + + IBsonSerializer enumerationSerializer = (IBsonSerializer)Activator.CreateInstance(serializerType, new object[] { serializer }); memberMap.SetSerializer(enumerationSerializer); } } diff --git a/src/Fluxera.StronglyTypedId.MongoDB/StronglyTypedIdSerializer.cs b/src/Fluxera.StronglyTypedId.MongoDB/StronglyTypedIdSerializer.cs index db95d8d..e04d513 100644 --- a/src/Fluxera.StronglyTypedId.MongoDB/StronglyTypedIdSerializer.cs +++ b/src/Fluxera.StronglyTypedId.MongoDB/StronglyTypedIdSerializer.cs @@ -16,6 +16,17 @@ public sealed class StronglyTypedIdSerializer : Serial where TStronglyTypedId : StronglyTypedId where TValue : IComparable { + private readonly IBsonSerializer idValueSerializer; + + /// + /// Initializes a new instance of the ; + /// + /// + public StronglyTypedIdSerializer(IBsonSerializer idValueSerializer) + { + this.idValueSerializer = idValueSerializer; + } + /// public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TStronglyTypedId value) { @@ -25,7 +36,14 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati } else { - BsonSerializer.Serialize(context.Writer, value.Value); + if(this.idValueSerializer != null) + { + this.idValueSerializer.Serialize(context, args, value.Value); + } + else + { + BsonSerializer.Serialize(context.Writer, value.Value); + } } } @@ -38,7 +56,17 @@ public override TStronglyTypedId Deserialize(BsonDeserializationContext context, return null; } - TValue value = BsonSerializer.Deserialize(context.Reader); + TValue value; + + if(this.idValueSerializer != null) + { + value = (TValue)this.idValueSerializer.Deserialize(context, args); + } + else + { + value = BsonSerializer.Deserialize(context.Reader); + } + object instance = Activator.CreateInstance(args.NominalType, new object[] { value }); return (TStronglyTypedId)instance; } diff --git a/src/Fluxera.StronglyTypedId/IStronglyTypedId.cs b/src/Fluxera.StronglyTypedId/IStronglyTypedId.cs index 9b042eb..c851aa9 100644 --- a/src/Fluxera.StronglyTypedId/IStronglyTypedId.cs +++ b/src/Fluxera.StronglyTypedId/IStronglyTypedId.cs @@ -10,7 +10,7 @@ /// [PublicAPI] public interface IStronglyTypedId : IComparable, IEquatable - where TKey : notnull + where TKey : notnull, IComparable { /// /// Gets the underlying value of the strongly-typed ID. diff --git a/tests/Fluxera.StronglyTypedId.MongoDB.UnitTests/ConverterTests.cs b/tests/Fluxera.StronglyTypedId.MongoDB.UnitTests/ConverterTests.cs index 9303cb0..c93357c 100644 --- a/tests/Fluxera.StronglyTypedId.MongoDB.UnitTests/ConverterTests.cs +++ b/tests/Fluxera.StronglyTypedId.MongoDB.UnitTests/ConverterTests.cs @@ -23,17 +23,17 @@ public class TestClass private static readonly TestClass TestInstance = new TestClass { - PersonId = new PersonId("12345") + PersonId = new PersonId("6299e4fda14ed1025f7a413e") }; - private static readonly string JsonString = @"{ ""PersonId"" : ""12345"" }"; + private static readonly string JsonString = @"{ ""PersonId"" : ObjectId(""6299e4fda14ed1025f7a413e"") }"; [Test] public void ShouldDeserialize() { TestClass obj = BsonSerializer.Deserialize(JsonString); - obj.PersonId.Should().Be(new PersonId("12345")); + obj.PersonId.Should().Be(new PersonId("6299e4fda14ed1025f7a413e")); } [Test]