1. Serialization of Net Core
1.1 json.Net
Common toolkits, such as Newtonsoft.Json, are components of serialization and deserialization based on json format
json.net has the following advantages:
Intrusivity: Serialization can be done without adding attribute s
Flexibility: Flexible configurations, such as allowing serialized members to customize names and masking non-serialized attribute members
Readability: Data format is simple and easy to read and write
Dependency: You can serialize to JObject without relying on objects for serialization and generics.
1.2 protobuf
It is a component of serialization and deserialization based on binary format
protobuf has the following advantages:
High performance: Serialized volume is smaller than Json and XML, suitable for RPC binary transmission
Cross-Language: Support for Cross-Platform Multilingualism
Compatibility: Message format upgrades and compatibility are good
Fast: Serialization deserialization is faster than Json's processing speed
1.3 messagepack
It is a component of serialization and deserialization based on binary format
messagepack has the following advantages:
High performance: Serialized volume is smaller than Json and XML, suitable for RPC binary transmission
Cross-Language: Support for Cross-Platform Multilingualism
Compatibility: Message format upgrades and compatibility are good
Fast: Serialization deserialization is faster than Json's processing speed
Message pack maintains stable performance in both small and large data volumes. In this paper, message pack serialization is used.
2. Project Coding and Design Patterns
The following is the file structure:
2.1 Factory Model
abstract class
/// <summary> /// An abstract factory for transmitting message codec. /// </summary> public interface ITransportMessageCodecFactory { /// <summary> /// Get the encoder. /// </summary> /// <returns>Encoder example.</returns> ITransportMessageEncoder GetEncoder(); /// <summary> /// Get the decoder. /// </summary> /// <returns>Examples of decoders.</returns> ITransportMessageDecoder GetDecoder(); }
/// <summary> /// Encoder /// </summary> public interface ITransportMessageEncoder { byte[] Encode(TransportMessage message); }
/// <summary> /// Decoder /// </summary> public interface ITransportMessageDecoder { TransportMessage Decode(byte[] data); }
Implementation class
public sealed class MessagePackTransportMessageCodecFactory : ITransportMessageCodecFactory { #region Field private readonly ITransportMessageEncoder _transportMessageEncoder = new MessagePackTransportMessageEncoder(); private readonly ITransportMessageDecoder _transportMessageDecoder = new MessagePackTransportMessageDecoder(); #endregion Field #region Implementation of ITransportMessageCodecFactory /// <inheritdoc /> /// <summary> /// Acquisition coder /// </summary> /// <returns></returns> public ITransportMessageEncoder GetEncoder() { return _transportMessageEncoder; } /// <inheritdoc /> /// <summary> /// Acquisition decoder /// </summary> /// <returns></returns> public ITransportMessageDecoder GetDecoder() { return _transportMessageDecoder; } #endregion Implementation of ITransportMessageCodecFactory }
public sealed class MessagePackTransportMessageEncoder : ITransportMessageEncoder { #region Implementation of ITransportMessageEncoder public byte[] Encode(TransportMessage transportMessage) { MessagePackTransportMessage messagePackTransportMessage = new MessagePackTransportMessage(transportMessage); return MessagePackSerializer.Serialize(messagePackTransportMessage); } #endregion Implementation of ITransportMessageEncoder }
public sealed class MessagePackTransportMessageDecoder : ITransportMessageDecoder { #region Implementation of ITransportMessageDecoder public TransportMessage Decode(byte[] data) { MessagePackTransportMessage messagePackTransportMessage = MessagePackSerializer.Deserialize<MessagePackTransportMessage>(data); return messagePackTransportMessage.GetTransportMessage(); } #endregion Implementation of ITransportMessageDecoder }
2.2 Decorator Model
public class TransportMessage { /// <summary> /// news Id. /// </summary> public string Id { get; set; } /// <summary> /// Message content. /// </summary> public object Content { get; set; } /// <summary> /// Content type. /// </summary> public string ContentType { get; set; } }
using MessagePack; [MessagePackObject] public class MessagePackTransportMessage { private TransportMessage _transportMessage; public MessagePackTransportMessage(): this(new TransportMessage()) { } public MessagePackTransportMessage(TransportMessage transportMessage) { this._transportMessage = transportMessage; } public TransportMessage GetTransportMessage() { return _transportMessage; } /// <summary> /// news Id. /// </summary> [Key(0)] public string Id { get { return _transportMessage.Id; } set { _transportMessage.Id = value; } } /// <summary> /// Message content. /// </summary> [Key(1)] public object Content { get { return _transportMessage.Content; } set { _transportMessage.Content = value; } } /// <summary> /// Content type. /// </summary> [Key(2)] public string ContentType { get { return _transportMessage.ContentType; } set { _transportMessage.ContentType = value; } } }
2.3 Dependency Injection
using Autofac; public static class ContainerBuilderExtensions { /// <summary> /// Use messagepack Coding and Decoding Method /// </summary> /// <param name="builder"></param> /// <returns></returns> public static ContainerBuilder UseMessagePackCodec(this ContainerBuilder builder) { builder.RegisterType(typeof(MessagePackTransportMessageCodecFactory)).As(typeof(ITransportMessageCodecFactory)).SingleInstance(); return builder; } }
2.4 Unit Testing
using MessagePack; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] public class MessagePackTest { [TestMethod] public void TestCodec() { Person person = new Person { Name = "Zhang Hongwei", Age = 18 }; TransportMessage transportMessage = new TransportMessage { Id = "1", ContentType = "Person", Content = person }; MessagePackTransportMessageCodecFactory factory = new MessagePackTransportMessageCodecFactory(); ITransportMessageEncoder encoder = factory.GetEncoder(); ITransportMessageDecoder decoder = factory.GetDecoder(); byte[] vs = encoder.Encode(transportMessage); TransportMessage message =decoder.Decode(vs); Assert.AreEqual(message.Id, "1"); Assert.AreEqual(message.ContentType, "Person"); Assert.AreEqual(((object[])message.Content)[0].ToString(), "Zhang Hongwei" ); Assert.AreEqual(((object[])message.Content)[1].ToString(), "18"); } [MessagePackObject] public class Person { [Key(0)] public string Name { get; set; } [Key(1)] public int Age { get; set; } } }