一個技術汪的開源夢 —— 目錄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 }
- 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 }
接口有了,對應的原生實現也有了,那咋用呢,還有我要不想用原生的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());