Quellcode durchsuchen

Rename Serializer into ProtoBufConvert

- Avoid name conflicts with ProtoBuf.Serializer
- Move clone method to MessageSerializer
Olivier Coanet vor 3 Jahren
Ursprung
Commit
3f890e1737

+ 3 - 3
src/Abc.Zebus.Persistence.Tests/Handlers/PersistMessageCommandHandlerTests.cs

@@ -47,7 +47,7 @@ namespace Abc.Zebus.Persistence.Tests.Handlers
             message.peerId.ShouldEqual(peerId);
             message.messageId.ShouldEqual(transportMessage.Id);
             message.messageTypeId.ShouldEqual(transportMessage.MessageTypeId);
-            message.transportMessageBytes.ShouldEqual(Serializer.Serialize(transportMessage).ToArray());
+            message.transportMessageBytes.ShouldEqual(ProtoBufConvert.Serialize(transportMessage).ToArray());
         }
 
         [Test]
@@ -90,14 +90,14 @@ namespace Abc.Zebus.Persistence.Tests.Handlers
 
             var message = new FakeCommand(1);
             var transportMessage = message.ToTransportMessage();
-            transportMessage.GetContentBytes().ShouldEqual(Serializer.Serialize(message).ToArray());
+            transportMessage.GetContentBytes().ShouldEqual(ProtoBufConvert.Serialize(message).ToArray());
 
             // Act
             _handler.Handle(new PersistMessageCommand(transportMessage, targetPeerId));
 
             // Assert
             replayerMock.Verify(x => x.AddLiveMessage(transportMessage));
-            transportMessage.GetContentBytes().ShouldEqual(Serializer.Serialize(message).ToArray());
+            transportMessage.GetContentBytes().ShouldEqual(ProtoBufConvert.Serialize(message).ToArray());
         }
 
         [Test, Repeat(5)]

+ 2 - 2
src/Abc.Zebus.Testing/MessageSerializationTester.cs

@@ -82,8 +82,8 @@ namespace Abc.Zebus.Testing
 
             Console.WriteLine("{{{0}}}", message);
 
-            var bytes = Serializer.Serialize(message);
-            var messageCopy = Serializer.Deserialize(messageType, bytes);
+            var bytes = ProtoBufConvert.Serialize(message);
+            var messageCopy = ProtoBufConvert.Deserialize(messageType, bytes);
 
             messageCopy.ShouldNotBeNull();
 

+ 2 - 2
src/Abc.Zebus.Tests/SerializationTests.cs

@@ -1,6 +1,7 @@
 using System;
 using System.IO;
 using Abc.Zebus.Routing;
+using Abc.Zebus.Serialization;
 using Abc.Zebus.Testing;
 using Abc.Zebus.Testing.Extensions;
 using Abc.Zebus.Tests.Messages;
@@ -8,7 +9,6 @@ using Abc.Zebus.Transport;
 using Newtonsoft.Json;
 using NUnit.Framework;
 using ProtoBuf;
-using Serializer = Abc.Zebus.Serialization.Serializer;
 
 namespace Abc.Zebus.Tests
 {
@@ -33,7 +33,7 @@ namespace Abc.Zebus.Tests
         [Test]
         public void should_deserialize_message_with_null_content()
         {
-            var message = Serializer.Deserialize(typeof(EmptyCommand), default) as EmptyCommand;
+            var message = ProtoBufConvert.Deserialize(typeof(EmptyCommand), ReadOnlyMemory<byte>.Empty) as EmptyCommand;
             message.ShouldNotBeNull();
         }
 

+ 1 - 1
src/Abc.Zebus.Tests/TestData.cs

@@ -20,7 +20,7 @@ namespace Abc.Zebus.Tests
         {
             var fixture = new Fixture();
             var message = fixture.Create<TMessage>();
-            var content = Serializer.Serialize(message);
+            var content = ProtoBufConvert.Serialize(message);
 
             return new TransportMessage(new MessageTypeId(typeof(TMessage)), content, new PeerId("Abc.Testing.0"), "tcp://testing:1234")
             {

+ 1 - 1
src/Abc.Zebus/Serialization/IMessageSerializer.cs

@@ -6,7 +6,7 @@ namespace Abc.Zebus.Serialization
     public interface IMessageSerializer
     {
         ReadOnlyMemory<byte> Serialize(IMessage message);
-        IMessage? Deserialize(MessageTypeId messageTypeId, ReadOnlyMemory<byte> stream);
+        IMessage? Deserialize(MessageTypeId messageTypeId, ReadOnlyMemory<byte> bytes);
         bool TryClone(IMessage message, [MaybeNullWhen(false)] out IMessage clone);
     }
 }

+ 22 - 4
src/Abc.Zebus/Serialization/MessageSerializer.cs

@@ -1,4 +1,5 @@
 using System;
+using System.IO;
 using Microsoft.Extensions.Logging;
 
 namespace Abc.Zebus.Serialization
@@ -7,11 +8,11 @@ namespace Abc.Zebus.Serialization
     {
         private static readonly ILogger _log = ZebusLogManager.GetLogger(typeof(MessageSerializer));
 
-        public IMessage? Deserialize(MessageTypeId messageTypeId, ReadOnlyMemory<byte> stream)
+        public IMessage? Deserialize(MessageTypeId messageTypeId, ReadOnlyMemory<byte> bytes)
         {
             var messageType = messageTypeId.GetMessageType();
             if (messageType != null)
-                return (IMessage)Serializer.Deserialize(messageType, stream);
+                return (IMessage)ProtoBufConvert.Deserialize(messageType, bytes);
 
             _log.LogWarning($"Could not find message type: {messageTypeId.FullName}");
             return null;
@@ -19,10 +20,27 @@ namespace Abc.Zebus.Serialization
 
         public ReadOnlyMemory<byte> Serialize(IMessage message)
         {
-            return Serializer.Serialize(message);
+            return ProtoBufConvert.Serialize(message);
         }
 
         public bool TryClone(IMessage message, out IMessage clone)
-            => Serializer.TryClone(message, out clone!);
+        {
+            var messageType = message.GetType();
+            if (ProtoBufConvert.CanSerialize(messageType))
+            {
+                // Cannot use the DeepClone method as it doesn't handle classes without a parameterless constructor
+
+                using var ms = new MemoryStream();
+
+                ProtoBufConvert.Serialize(ms, message!);
+                ms.Position = 0;
+                clone = (IMessage)ProtoBufConvert.Deserialize(messageType, ms);
+
+                return true;
+            }
+
+            clone = null!;
+            return false;
+        }
     }
 }

+ 7 - 34
src/Abc.Zebus/Serialization/Serializer.cs → src/Abc.Zebus/Serialization/ProtoBufConvert.cs

@@ -8,7 +8,7 @@ using ProtoBuf.Meta;
 
 namespace Abc.Zebus.Serialization
 {
-    internal static class Serializer
+    internal static class ProtoBufConvert
     {
         private static readonly ConcurrentDictionary<Type, bool> _hasParameterLessConstructorByType = new ConcurrentDictionary<Type, bool>();
 
@@ -20,7 +20,7 @@ namespace Abc.Zebus.Serialization
             return new ReadOnlyMemory<byte>(stream.GetBuffer(), 0, (int)stream.Position);
         }
 
-        private static void Serialize(Stream stream, object message)
+        public static void Serialize(Stream stream, object message)
         {
             try
             {
@@ -32,23 +32,15 @@ namespace Abc.Zebus.Serialization
             }
         }
 
-        [return: NotNullIfNotNull("messageType")]
-        public static object? Deserialize(Type? messageType, ReadOnlyMemory<byte> bytes)
+        public static object Deserialize(Type messageType, ReadOnlyMemory<byte> bytes)
         {
-            if (messageType is null)
-                return null;
-
             var obj = CreateMessageIfRequired(messageType);
 
             return RuntimeTypeModel.Default.Deserialize(bytes, type: messageType, value: obj);
         }
 
-        [return: NotNullIfNotNull("messageType")]
-        private static object? Deserialize(Type? messageType, Stream stream)
+        public static object Deserialize(Type messageType, Stream stream)
         {
-            if (messageType is null)
-                return null;
-
             var obj = CreateMessageIfRequired(messageType);
 
             return RuntimeTypeModel.Default.Deserialize(stream, value: obj, type: messageType);
@@ -62,33 +54,14 @@ namespace Abc.Zebus.Serialization
             return null;
         }
 
-        public static bool TryClone<T>(T? message, [NotNullWhen(true)] out T? clone)
-            where T : class
-        {
-            var messageType = message?.GetType();
-            if (messageType != null && RuntimeTypeModel.Default.CanSerialize(messageType))
-            {
-                // Cannot use the DeepClone method as it doesn't handle classes without a parameterless constructor
-
-                using (var ms = new MemoryStream())
-                {
-                    Serialize(ms, message!);
-                    ms.Position = 0;
-                    clone = (T)Deserialize(messageType, ms);
-                }
-
-                return true;
-            }
-
-            clone = null;
-            return false;
-        }
-
         [SuppressMessage("ReSharper", "ConvertClosureToMethodGroup")]
         private static bool HasParameterLessConstructor(Type messageType)
             => _hasParameterLessConstructorByType.GetOrAdd(messageType, type => ComputeHasParameterLessConstructor(type));
 
         private static bool ComputeHasParameterLessConstructor(Type type)
             => type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null) != null;
+
+        public static bool CanSerialize([NotNullWhen(true)] Type? messageType)
+            => messageType != null && RuntimeTypeModel.Default.CanSerialize(messageType);
     }
 }