• 一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之序列化


    一个技术汪的开源梦 —— 目录

          想必大家在项目中都接触过 JSON 或者 XML 吧,为了将对象在网络上传输或者将其持久化必须将其序列化为一个字符串然后进行后续操作。常见的就是将其序列化成 JSON 或者 XML 。

          大家在项目中应该都看到过这样的工具类 例如 ***XmlHelper、***JsonHelper 等,没错这一些助手类会帮助我们重复造轮子。既然是组件并且还是是开源的必须考虑每个功能的后续可扩展性以及易用性。

    ISerializer 序列化者接口

     1 using System;
     2 
     3 namespace Wlitsoft.Framework.Common.Abstractions.Serialize
     4 {
     5     /// <summary>
     6     /// 序列化者接口。
     7     /// </summary>
     8     public interface ISerializer
     9     {
    10         /// <summary>
    11         /// 获取序列化类型。
    12         /// </summary>
    13         SerializeType SerializeType { get; }
    14 
    15         /// <summary>
    16         /// 将一个对象序列化成一个字符串。
    17         /// </summary>
    18         /// <param name="obj">要序列化的对象。</param>
    19         /// <returns>序列化后的字符串。</returns>
    20         string Serialize(object obj);
    21 
    22         /// <summary>
    23         /// 将一个字符串反序列化为一个对象。
    24         /// </summary>
    25         /// <param name="objType">要反序序列化的对象类型。</param>
    26         /// <param name="str">要反序列化的字符串。</param>
    27         /// <returns>反序列化得到的对象。</returns>
    28         object Deserialize(Type objType, string str);
    29 
    30         /// <summary>
    31         /// 将一个字符串反序列化为一个对象。
    32         /// </summary>
    33         /// <param name="str">要反序列化的字符串。</param>
    34         /// <returns>反序列化得到的对象。</returns>
    35         T Deserialize<T>(string str);
    36     }
    37 }

    该接口很简单就一个属性标示序列化类型、序列化方法、反序列化方法。

    SerializeType 序列化类型

     1 namespace Wlitsoft.Framework.Common.Abstractions.Serialize
     2 {
     3     /// <summary>
     4     /// 序列化类型。
     5     /// </summary>
     6     public enum SerializeType
     7     {
     8         /// <summary>
     9         /// Xml。
    10         /// </summary>
    11         Xml,
    12 
    13         /// <summary>
    14         /// Json。
    15         /// </summary>
    16         Json
    17     }
    18 }

     一个枚举标识使用哪种序列化方式。

    类型有了那对应的原始的实现肯定少不了。

     - JsonSerializer Json 序列化/反序列化。

     1 using System;
     2 using System.IO;
     3 using System.Runtime.Serialization.Json;
     4 using System.Text;
     5 using Wlitsoft.Framework.Common.Abstractions.Serialize;
     6 using Wlitsoft.Framework.Common.Exception;
     7 
     8 namespace Wlitsoft.Framework.Common.Serialize
     9 {
    10     /// <summary>
    11     /// Json 序列化/反序列化。
    12     /// </summary>
    13     public class JsonSerializer : ISerializer
    14     {
    15         #region ISerializer 成员
    16 
    17         /// <summary>
    18         /// 获取序列化类型。
    19         /// </summary>
    20         public SerializeType SerializeType { get; } = SerializeType.Json;
    21 
    22         /// <summary>
    23         /// 将一个对象序列化成一个字符串。
    24         /// </summary>
    25         /// <param name="obj">要序列化的对象。</param>
    26         /// <returns>序列化后的字符串。</returns>
    27         public string Serialize(object obj)
    28         {
    29             #region  参数校验
    30 
    31             if (obj == null)
    32                 throw new ObjectNullException(nameof(obj));
    33 
    34             #endregion
    35 
    36             using (var ms = new MemoryStream())
    37             {
    38                 new DataContractJsonSerializer(obj.GetType()).WriteObject(ms, obj);
    39                 return Encoding.UTF8.GetString(ms.ToArray());
    40             }
    41 
    42         }
    43 
    44         /// <summary>
    45         /// 将一个字符串反序列化为一个对象。
    46         /// </summary>
    47         /// <param name="objType">要反序序列化的对象类型。</param>
    48         /// <param name="str">要反序列化的字符串。</param>
    49         /// <returns>反序列化得到的对象。</returns>
    50         public object Deserialize(Type objType, string str)
    51         {
    52             #region 参数校验
    53 
    54             if (objType == null)
    55                 throw new ObjectNullException(nameof(objType));
    56 
    57             if (string.IsNullOrEmpty(str))
    58                 throw new StringNullOrEmptyException(nameof(str));
    59 
    60             #endregion
    61 
    62             using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str)))
    63             {
    64                 return new DataContractJsonSerializer(objType).ReadObject(ms);
    65             }
    66         }
    67 
    68         /// <summary>
    69         /// 将一个字符串反序列化为一个对象。
    70         /// </summary>
    71         /// <param name="str">要反序列化的字符串。</param>
    72         /// <returns>反序列化得到的对象。</returns>
    73         public T Deserialize<T>(string str)
    74         {
    75             #region 参数校验
    76 
    77             if (string.IsNullOrEmpty(str))
    78                 throw new StringNullOrEmptyException(nameof(str));
    79 
    80             #endregion
    81 
    82             return (T)this.Deserialize(typeof(T), str);
    83         }
    84 
    85         #endregion
    86     }
    87 }
    JsonSerializer

     - XmlSerializer Xml 序列化/反序列化。

      1 using System;
      2 using System.IO;
      3 using System.Text;
      4 using System.Xml;
      5 using System.Xml.Serialization;
      6 using Wlitsoft.Framework.Common.Abstractions.Serialize;
      7 using Wlitsoft.Framework.Common.Exception;
      8 
      9 namespace Wlitsoft.Framework.Common.Serialize
     10 {
     11     /// <summary>
     12     /// Xml 序列化/反序列化。
     13     /// </summary>
     14     public class XmlSerializer : ISerializer
     15     {
     16         #region ISerializer 成员
     17 
     18         /// <summary>
     19         /// 获取序列化类型。
     20         /// </summary>
     21         public SerializeType SerializeType { get; } = SerializeType.Xml;
     22 
     23         /// <summary>
     24         /// 将一个对象序列化成一个字符串。
     25         /// </summary>
     26         /// <param name="obj">要序列化的对象。</param>
     27         /// <returns>序列化后的字符串。</returns>
     28         public string Serialize(object obj)
     29         {
     30             #region  参数校验
     31 
     32             if (obj == null)
     33                 throw new ObjectNullException(nameof(obj));
     34 
     35             #endregion
     36 
     37             System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
     38 
     39             //去除默认的命名空间声明。
     40             XmlSerializerNamespaces xmlNamespaces = new XmlSerializerNamespaces();
     41             xmlNamespaces.Add("", "");
     42 
     43             XmlWriterSettings settings = new XmlWriterSettings();
     44             settings.OmitXmlDeclaration = true;
     45             settings.Indent = true;
     46             settings.NewLineChars = "
    ";
     47             settings.IndentChars = "    ";
     48 
     49             MemoryStream outStream = new MemoryStream();
     50             using (XmlWriter writer = XmlWriter.Create(outStream, settings))
     51             {
     52                 serializer.Serialize(writer, obj, xmlNamespaces);
     53             }
     54 
     55             outStream.Position = 0;
     56             using (StreamReader reader = new StreamReader(outStream))
     57             {
     58                 return reader.ReadToEnd();
     59             }
     60         }
     61 
     62         /// <summary>
     63         /// 将一个字符串反序列化为一个对象。
     64         /// </summary>
     65         /// <param name="objType">要反序序列化的对象类型。</param>
     66         /// <param name="str">要反序列化的字符串。</param>
     67         /// <returns>反序列化得到的对象。</returns>
     68         public object Deserialize(Type objType, string str)
     69         {
     70             #region 参数校验
     71 
     72             if (objType == null)
     73                 throw new ObjectNullException(nameof(objType));
     74 
     75             if (string.IsNullOrEmpty(str))
     76                 throw new StringNullOrEmptyException(nameof(str));
     77 
     78             #endregion
     79 
     80             System.Xml.Serialization.XmlSerializer mySerializer = new System.Xml.Serialization.XmlSerializer(objType);
     81             using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(str)))
     82             {
     83                 using (StreamReader sr = new StreamReader(ms))
     84                 {
     85                     return mySerializer.Deserialize(sr);
     86                 }
     87             }
     88         }
     89 
     90         /// <summary>
     91         /// 将一个字符串反序列化为一个对象。
     92         /// </summary>
     93         /// <param name="str">要反序列化的字符串。</param>
     94         /// <returns>反序列化得到的对象。</returns>
     95         public T Deserialize<T>(string str)
     96         {
     97             #region 参数校验
     98 
     99             if (string.IsNullOrEmpty(str))
    100                 throw new StringNullOrEmptyException(nameof(str));
    101 
    102             #endregion
    103 
    104             return (T)this.Deserialize(typeof(T), str);
    105         }
    106 
    107         #endregion
    108 
    109     }
    110 }
    XmlSerializer

    接口有了,对应的原生实现也有了,那咋用呢,还有我要不想用原生的Json 序列化方式咋办比如想用 JSON.Net 别急继续往下 See。

    SerializerFactory 序列化工厂

    把它定义成工厂确实有些牵强但是没有想到很好的名称 那就暂时先就叫工厂吧。它主要存储所有的序列化者对象实例、可以获取实例、亦可以重新设置实例。下面只列出方法签名。

    /// <summary>
    /// 获取一个 <see cref="ISerializer"/> 的实例。
    /// </summary>
    /// <param name="type">序列化类型。</param>
    /// <returns>一个 <see cref="ISerializer"/> 类型的对象实例。</returns>
    public ISerializer GetSerializer(SerializeType type)
    /// <summary>
    /// 获取一个 <see cref="ISerializer"/> 的实例。
    /// </summary>
    /// <param name="type">序列化类型。</param>
    /// <returns>一个 <see cref="ISerializer"/> 类型的对象实例。</returns>
    public ISerializer GetSerializer(SerializeType type)

    现在可以使用了,等下 还没完。。。 为了更便于使用它们 将其做成 扩展方法。

    ObjectExtensions 对象扩展方法静态类。

     1 /// <summary>
     2 /// 将 json 字符串转换为指定类型的对象表示形式。
     3 /// </summary>
     4 /// <typeparam name="T">要转换成的对象类型。</typeparam>
     5 /// <param name="json">json 字符串。</param>
     6 /// <returns>转换完后的 JSON 对象。</returns>
     7 public static T ToJsonObject<T>(this string json)
     8 {
     9     #region 参数校验
    10 
    11     if (string.IsNullOrEmpty(json))
    12         throw new StringNullOrEmptyException(nameof(json));
    13 
    14     #endregion
    15 
    16     ISerializer serializer = GlobalConfig.SerializerFactory.GetJsonSerializer();
    17     return serializer.Deserialize<T>(json);
    18 }
     1 /// <summary>
     2 /// 将给定 XML 字符串(<see paracref="xml"/>)转换为指定类型的对象表示形式。
     3 /// </summary>
     4 /// <typeparam name="T">要转换成的对象类型。</typeparam>
     5 /// <param name="xml">json 字符串。</param>
     6 /// <returns>转换完后的 Xml 对象。</returns>
     7 public static T ToXmlObject<T>(this string xml)
     8 {
     9     #region 参数校验
    10 
    11     if (string.IsNullOrEmpty(xml))
    12         throw new StringNullOrEmptyException(nameof(xml));
    13 
    14     #endregion
    15 
    16     ISerializer serializer = GlobalConfig.SerializerFactory.GetXmlSerializer();
    17     return serializer.Deserialize<T>(xml);
    18 }

    StringExtensions 字符串类型扩展方法静态类。 

     1 /// <summary>
     2 /// 将给定对象(<paramref name="obj"/>)转换成 JSON 字符串的表示形式。
     3 /// </summary>
     4 /// <param name="obj">准备进行转换的对象。</param>
     5 /// <returns>转换后生成的 JSON 字符串。</returns>
     6 public static string ToJsonString(this object obj)
     7 {
     8     #region 参数校验
     9 
    10     if (obj == null)
    11         throw new ObjectNullException(nameof(obj));
    12 
    13     #endregion
    14 
    15     ISerializer serializer = GlobalConfig.SerializerFactory.GetJsonSerializer();
    16     return serializer.Serialize(obj);
    17 }
     1 /// <summary>
     2 /// 将给定 XML 字符串(<see paracref="xml"/>)转换为指定类型的对象表示形式。
     3 /// </summary>
     4 /// <typeparam name="T">要转换成的对象类型。</typeparam>
     5 /// <param name="xml">json 字符串。</param>
     6 /// <returns>转换完后的 Xml 对象。</returns>
     7 public static T ToXmlObject<T>(this string xml)
     8 {
     9     #region 参数校验
    10 
    11     if (string.IsNullOrEmpty(xml))
    12         throw new StringNullOrEmptyException(nameof(xml));
    13 
    14     #endregion
    15 
    16     ISerializer serializer = GlobalConfig.SerializerFactory.GetXmlSerializer();
    17     return serializer.Deserialize<T>(xml);
    18 }

    关于扩展性

    回到刚才那个问题,如果我不想用原生的 Json 序列化方式咋办,难不成字符串扩展以及对象扩展这些方法都用不了了吗。别急继续往下看。

     

    Common.JsonNet.JsonSerializer 公共类库 Json.Net 组件序列化者。

    该项目中  JsonNetJsonSerializer  实现了  ISerializer 接口,也就是说这个类有序列化和反序列化的能力,那类有了怎么用呢。

    当然你可以直接 new 一个 JsonNetJsonSerializer 的实例 然后使用。但是这样的话就有点本末倒置了。

    GlobalConfig 全局配置静态类

    这个类中后续会有好多属性 可以修改 Common 包内部的一些实现方式。

    比如:将 Common 包中原生的 Json 序列化实现用 JSON.Net 取缔只需要 在 网站的 Startup 或者 控制台中的 静态构造方法中写入下面一行代码即可。

    1 GlobalConfig.SerializerFactory.SetSerializer(SerializeType.Json,new JsonNetJsonSerializer());

    一个技术汪的开源梦 —— 目录 

  • 相关阅读:
    Less资源汇总
    Less函数说明
    Less使用说明
    Less 简介
    tomcat-users.xml 配置
    java project打包生成jar包(通用)
    5分钟理解String的'+'的性能及原理
    字符串"+"操作的原理
    Shell脚本实现对文件编辑
    mysql关于聚集索引、非聚集索引的总结
  • 原文地址:https://www.cnblogs.com/wlitsoft/p/6033140.html
Copyright © 2020-2023  润新知