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

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

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

ISerializer 序列化者接口

 using System;

 namespace Wlitsoft.Framework.Common.Abstractions.Serialize
{
/// <summary>
/// 序列化者接口。
/// </summary>
public interface ISerializer
{
/// <summary>
/// 获取序列化类型。
/// </summary>
SerializeType SerializeType { get; } /// <summary>
/// 将一个对象序列化成一个字符串。
/// </summary>
/// <param name="obj">要序列化的对象。</param>
/// <returns>序列化后的字符串。</returns>
string Serialize(object obj); /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="objType">要反序序列化的对象类型。</param>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
object Deserialize(Type objType, string str); /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
T Deserialize<T>(string str);
}
}

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

SerializeType 序列化类型

 namespace Wlitsoft.Framework.Common.Abstractions.Serialize
{
/// <summary>
/// 序列化类型。
/// </summary>
public enum SerializeType
{
/// <summary>
/// Xml。
/// </summary>
Xml, /// <summary>
/// Json。
/// </summary>
Json
}
}

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

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

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

 using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
using Wlitsoft.Framework.Common.Abstractions.Serialize;
using Wlitsoft.Framework.Common.Exception; namespace Wlitsoft.Framework.Common.Serialize
{
/// <summary>
/// Json 序列化/反序列化。
/// </summary>
public class JsonSerializer : ISerializer
{
#region ISerializer 成员 /// <summary>
/// 获取序列化类型。
/// </summary>
public SerializeType SerializeType { get; } = SerializeType.Json; /// <summary>
/// 将一个对象序列化成一个字符串。
/// </summary>
/// <param name="obj">要序列化的对象。</param>
/// <returns>序列化后的字符串。</returns>
public string Serialize(object obj)
{
#region 参数校验 if (obj == null)
throw new ObjectNullException(nameof(obj)); #endregion using (var ms = new MemoryStream())
{
new DataContractJsonSerializer(obj.GetType()).WriteObject(ms, obj);
return Encoding.UTF8.GetString(ms.ToArray());
} } /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="objType">要反序序列化的对象类型。</param>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
public object Deserialize(Type objType, string str)
{
#region 参数校验 if (objType == null)
throw new ObjectNullException(nameof(objType)); if (string.IsNullOrEmpty(str))
throw new StringNullOrEmptyException(nameof(str)); #endregion using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str)))
{
return new DataContractJsonSerializer(objType).ReadObject(ms);
}
} /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
public T Deserialize<T>(string str)
{
#region 参数校验 if (string.IsNullOrEmpty(str))
throw new StringNullOrEmptyException(nameof(str)); #endregion return (T)this.Deserialize(typeof(T), str);
} #endregion
}
}

JsonSerializer

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

 using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using Wlitsoft.Framework.Common.Abstractions.Serialize;
using Wlitsoft.Framework.Common.Exception; namespace Wlitsoft.Framework.Common.Serialize
{
/// <summary>
/// Xml 序列化/反序列化。
/// </summary>
public class XmlSerializer : ISerializer
{
#region ISerializer 成员 /// <summary>
/// 获取序列化类型。
/// </summary>
public SerializeType SerializeType { get; } = SerializeType.Xml; /// <summary>
/// 将一个对象序列化成一个字符串。
/// </summary>
/// <param name="obj">要序列化的对象。</param>
/// <returns>序列化后的字符串。</returns>
public string Serialize(object obj)
{
#region 参数校验 if (obj == null)
throw new ObjectNullException(nameof(obj)); #endregion System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType()); //去除默认的命名空间声明。
XmlSerializerNamespaces xmlNamespaces = new XmlSerializerNamespaces();
xmlNamespaces.Add("", ""); XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Indent = true;
settings.NewLineChars = "\r\n";
settings.IndentChars = " "; MemoryStream outStream = new MemoryStream();
using (XmlWriter writer = XmlWriter.Create(outStream, settings))
{
serializer.Serialize(writer, obj, xmlNamespaces);
} outStream.Position = ;
using (StreamReader reader = new StreamReader(outStream))
{
return reader.ReadToEnd();
}
} /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="objType">要反序序列化的对象类型。</param>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
public object Deserialize(Type objType, string str)
{
#region 参数校验 if (objType == null)
throw new ObjectNullException(nameof(objType)); if (string.IsNullOrEmpty(str))
throw new StringNullOrEmptyException(nameof(str)); #endregion System.Xml.Serialization.XmlSerializer mySerializer = new System.Xml.Serialization.XmlSerializer(objType);
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(str)))
{
using (StreamReader sr = new StreamReader(ms))
{
return mySerializer.Deserialize(sr);
}
}
} /// <summary>
/// 将一个字符串反序列化为一个对象。
/// </summary>
/// <param name="str">要反序列化的字符串。</param>
/// <returns>反序列化得到的对象。</returns>
public T Deserialize<T>(string str)
{
#region 参数校验 if (string.IsNullOrEmpty(str))
throw new StringNullOrEmptyException(nameof(str)); #endregion return (T)this.Deserialize(typeof(T), str);
} #endregion }
}

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 对象扩展方法静态类。

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

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

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

关于扩展性

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

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

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

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

GlobalConfig 全局配置静态类

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

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

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

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

一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之序列化的更多相关文章

  1. 一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之 Http 请求客户端

    一个技术汪的开源梦 —— 目录 想必大家在项目开发的时候应该都在程序中调用过自己内部的接口或者使用过第三方提供的接口,咱今天不讨论 REST ,最常用的请求应该就是 GET 和 POST 了,那下面开 ...

  2. 一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之目录结构

    一个技术汪的开源梦 —— 目录 这篇文章是开源公共组件的开篇那就先说说项目的 Github 目录结构和 .Net Core 的项目结构. 1. GitHub 目录结构和相关文件 - src 源码项目目 ...

  3. 一个技术汪的开源梦 —— 基于 .Net Core 的组件 Nuget 包制作 & 发布

    一个技术汪的开源梦 —— 目录 微软的 ASP.Net Core 强化了 Nuget 的使用,所有的 .Net Core 组件均有 Nuget 管理,所以有必要探讨一下 .Net Core 组件制作 ...

  4. 一个技术汪的开源梦 —— 微信开发工具包(WeixinSDK)

    由于春节的关系 WeixinSDK 这个开源项目的进展比预期推迟了大约一个月的时间,值得高兴的是到目前为止该项目的重要模块已经开发完毕.  - 关于项目 该项目的背景是现在微信公众号.微信服务号乃至微 ...

  5. 一个技术汪的开源梦 —— 公共组件缓存之分布式缓存 Redis 实现篇

    Redis 安装 & 配置 本测试环境将在 CentOS 7 x64 上安装最新版本的 Redis. 1. 运行以下命令安装 Redis $ wget http://download.redi ...

  6. 统一流控服务开源:基于.Net Core的流控服务

    先前有一篇博文,梳理了流控服务的场景.业界做法和常用算法 统一流控服务开源-1:场景&业界做法&算法篇 最近完成了流控服务的开发,并在生产系统进行了大半年的验证,稳定可靠.今天整理一下 ...

  7. 开源一个自己造的轮子:基于图的任务流引擎GraphScheduleEngine

    GraphScheduleEngine是什么: GraphScheduleEngine是一个基于DAG图的任务流引擎,不同语言编写.运行于不同机器上的模块.程序,均可以通过订阅GraphSchedul ...

  8. prime 又一个开源的基于graphql 的cms

    prime 是一个开源的基于graphql 的cms,类似的已经又好多了,strapi 就是一个(graphql 是通过插件扩展的) graphcms 是一款不错的,但是是收费的,prime 是基于t ...

  9. [PHP] 一个免费、开源的基于tp5+layui2.1.5开发的快速开发框架

    推荐 一个免费.开源的基于tp5+layui2.1.5开发的快速开发框架,既可以用来学习,也可以用来实际项目的快速开发: 码云下载:https://gitee.com/eduaskcms/eduask ...

随机推荐

  1. 【每日一linux命令4】常用参数:

     下面所列的是常见的参数(选项)义: --help,-h                              显示帮助信息 --version,-V                        ...

  2. ajax异步请求

    做前端开发的朋友对于ajax异步更新一定印象深刻,作为刚入坑的小白,今天就和大家一起聊聊关于ajax异步请求的那点事.既然是ajax就少不了jQuery的知识,推荐大家访问www.w3school.c ...

  3. CSS float 浮动属性

    本篇主要介绍float属性:定义元素朝哪个方向浮动. 目录: 1. 页面布局方式:介绍文档流.浮动层以及float属性. 2. float:left :介绍float为 left 时的布局方式. 3. ...

  4. UWP开发之Mvvmlight实践八:为什么事件注销处理要写在OnNavigatingFrom中

    前一段开发UWP应用的时候因为系统返回按钮事件(SystemNavigationManager.GetForCurrentView().BackRequested)浪费了不少时间.现象就是在手机版的详 ...

  5. error C4430:missing type specifier 解决错误

    错误    3    error C4430: missing type specifier - int assumed. Note: C++ does not support default-int ...

  6. Android中Fragment的两种创建方式

    fragment是Activity中用户界面的一个行为或者是一部分.你可以在一个单独的Activity上把多个Fragment组合成为一个多区域的UI,并且可以在多个Activity中再使用.你可以认 ...

  7. Atitit 软件工程概览attilax总结

    Atitit 软件工程概览attilax总结 1.1. .2 软件工程的发展 进一步地,结合人类发展史和计算机世界演化史来考察软件工程的发展史. 表2 软件工程过程模型 表2将软件工程的主要过程模型做 ...

  8. 在redis中使用lua脚本让你的灵活性提高5个逼格

    在redis的官网上洋洋洒洒的大概提供了200多个命令,貌似看起来很多,但是这些都是别人预先给你定义好的,但你却不能按照自己的意图进行定制, 所以是不是感觉自己还是有一种被束缚的感觉,有这个感觉就对了 ...

  9. MySQL Workbench建表时 PK NN UQ BIN UN ZF AI 的含义

    [转自网络]https://my.oschina.net/cers/blog/292191 PK Belongs to primary key 作为主键 NN Not Null 非空 UQ Uniqu ...

  10. mysql5.x升级至mysql5.7后导入之前数据库date出错的解决方法!

    mysql5.x升级至mysql5.7后导入之前数据库date出错的解决方法! 修改mysql5.7的配置文件即可解决,方法如下: linux版:找到mysql的安装路径进入默认的为/usr/shar ...