一個技術汪的開源夢 —— 基於 .Net Core 的公共組件之序列化

一個技術汪的開源夢 —— 目錄html

      想必你們在項目中都接觸過 JSON 或者 XML 吧,爲了將對象在網絡上傳輸或者將其持久化必須將其序列化爲一個字符串而後進行後續操做。常見的就是將其序列化成 JSON 或者 XML 。json

      你們在項目中應該都看到過這樣的工具類 例如 ***XmlHelper、***JsonHelper 等,沒錯這一些助手類會幫助咱們重複造輪子。既然是組件而且仍是是開源的必須考慮每一個功能的後續可擴展性以及易用性。網絡

ISerializer 序列化者接口ide

 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 序列化類型post

 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 }

 一個枚舉標識使用哪一種序列化方式。網站

 

類型有了那對應的原始的實現確定少不了。this

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

 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 序列化/反序列化。spa

  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 = "\r\n";
 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());

一個技術汪的開源夢 —— 目錄 

相關文章
相關標籤/搜索