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

想必大家在项目中都接触过 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. opencv在图像显示中文

    在图像定位和模式识别时,经常需要把结果标注到图片上,标注内容可以是数字字母.矩形框等(opencv支持的)或者是中文汉字(借助freetype). 1.显示数字/矩形框 #include <op ...

  2. 一个粗心的Bug,JSON格式不规范导致AJAX错误

    一.事件回放  今天工作时碰到了一个奇怪的问题,这个问题很早很早以前也碰到过,不过没想到过这么久了竟然又栽在这里. 当时正在联调一个项目,由于后端没有提供数据接口,于是我直接本地建立了一个 json ...

  3. .NET Core中间件的注册和管道的构建(1)---- 注册和构建原理

    .NET Core中间件的注册和管道的构建(1)---- 注册和构建原理 0x00 问题的产生 管道是.NET Core中非常关键的一个概念,很多重要的组件都以中间件的形式存在,包括权限管理.会话管理 ...

  4. Python高手之路【五】python基础之正则表达式

    下图列出了Python支持的正则表达式元字符和语法: 字符点:匹配任意一个字符 import re st = 'python' result = re.findall('p.t',st) print( ...

  5. PHP赋值运算

    1. 赋值运算:= ,意思是右边表达式的值赋给左边的运算数. $int1=10; $int1=$int1-6; //$int1=4 echo $int1,"<br>"; ...

  6. 【微信小程序开发】之如何获取免费ssl证书【图文步骤】

    微信小程序要求所有网络请求都走ssl加密,因此我们开发服务端接口需要配置为https 这篇文章介绍一下如何 在 startssl 申请一个免费的ca证书. 1. 打开网站  https://www.s ...

  7. 【干货分享】流程DEMO-资产请购单

    流程名: 资产请购  业务描述: 流程发起时,会检查预算,如果预算不够,流程必须经过总裁审批,如果预算够用,将发起流程,同时占用相应金额的预算,但撤销流程会释放相应金额的预算.  流程相关文件: 流程 ...

  8. JAVA的内存模型(变量的同步)

    一个线程中变量的修改可能不会立即对其他线程可见,事实上也许永远不可见. 在代码一中,如果一个线程调用了MyClass.loop(),将来的某个时间点,另一个线程调用了MyClass.setValue( ...

  9. SqlServer之数据库三大范式

    分析: 数据库设计应遵循三大范式分别为: 第一范式:确保表中每列的原子性(不可拆分): 第二范式:确保表中每列与主键相关,而不能只与主键的某部分相关(主要针对联合主键),主键列与非主键列遵循完全函数依 ...

  10. MySQL全文索引 FULLTEXT索引和like的区别

    1.概要 InnoDB引擎对FULLTEXT索引的支持是MySQL5.6新引入的特性,之前只有MyISAM引擎支持FULLTEXT索引.对于FULLTEXT索引的内容可以使用MATCH()-AGAIN ...