微服务实战(六):落地微服务架构到直销系统(事件存储)

在CQRS架构中,一个比较重要的内容就是当命令处理器从命令队列中接收到相关的命令数据后,通过调用领域对象逻辑,然后将当前事件的对象数据持久化到事件存储中。主要的用途是能够快速持久化对象此次的状态,另外也可以通过未来最终一致性的需求,通过事件数据将对象还原到一个特定的状态,这个状态通常是通过对象事件的版本来进行还原的。

要实现一个事件存储的框架,我们通常需要实现以下几个方面:

clipboard.png

1.对象事件的存储表

我们通常将对象某个变化的事件数据存储到数据库的表中,通常采用关系型数据库进行存储,这里使用SQL Server。

clipboard.png

AggregationRootId是当前聚合根对象的Id;AssemblyQualifiedAggreateRooType是当前聚合根对象的FQDN名,在C#代码中对应名称空间+类名(例如:Order.Domain.POCOModels.Orders, Order.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null);AssemblyQualifiedCommandAndEventType是操作当前聚合根的事件类型的FQDN名字,在C#代码中对应名称空间+类名(例如:Events.OrderCommands.CreateOrderCommand, Events, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null),Version对应的是针对某个聚合根当前事件操作的版本,通常对一个聚合根进行操作,版本就加1,Data则包括当前事件操作后,对象的当前状态数据。

2.重构Event用以支持存储

前面文章实现的事件只是用于标识消息,在事件需要存储时,我们需要更多的属性,包括聚合根ID,聚合根类型,操作聚合根的事件类型,版本号等。

public interface IEvent

{Guid Id { get; set; }DateTime CreateDate { get; set; }Guid AggregationRootId { get; set; }string AssemblyQualifiedAggreateRooType { get; set; }string AssemblyQualifiedCommandAndEventType { get; set; }int Version { get; set; }
}

public class BaseEvent : IEvent

{public Guid Id { get; set; }public DateTime CreateDate { get; set; }public Guid AggregationRootId { get; set; }public string AssemblyQualifiedAggreateRooType { get; set; }public string AssemblyQualifiedCommandAndEventType { get; set; }public int Version { get; set; }public BaseEvent(){this.Id = Guid.NewGuid();this.CreateDate = DateTime.Now;}
}

3.实现存储的事件对象

其实这里要实现的就是将事件和事件对象之间做相互的转换,用于未来存储事件或将事件反序列化成事件对象进行使用。

public class EventObject:BaseEvent

{        public byte[] Data { get; set; }public static EventObject FromDomainEvent(IEvent idomainevent){var domaineventobject = new EventObject();domaineventobject.Id = idomainevent.Id;domaineventobject.CreateDate = idomainevent.CreateDate;domaineventobject.Version = idomainevent.Version;domaineventobject.AggregationRootId = idomainevent.AggregationRootId;domaineventobject.AssemblyQualifiedAggreateRooType = idomainevent.AssemblyQualifiedAggreateRooType;domaineventobject.AssemblyQualifiedCommandAndEventType = idomainevent.AssemblyQualifiedCommandAndEventType;domaineventobject.Data = XmlObjectSerializer.Serialize(idomainevent);return domaineventobject;}public  IEvent ToDomainEvent(){            Type type = Type.GetType(this.AssemblyQualifiedAggreateRooType);var domainevent = (IEvent)XmlObjectSerializer.Deserialize(type, this.Data);domainevent.Id = this.Id;return domainevent;}
}

FromDomainEvent方法就是将事件信息转换为以后要存储的事件对象,ToDomainEvent就是将事件对象转换为事件。

4.实现事件存储

实现事件存储就是将领域事件对象存储到我们前面创建的数据库表中。为了能够快速存储,我们并不采用ORM框架,而是直接使用ADO.NET完成事件对象的存储。

public void SaveEvent(IEvent idomainevent)

    {try{var domaineventobject = EventObject.FromDomainEvent(idomainevent);conn.Open();SqlParameter sqlparm = new SqlParameter("@AggregationRootId", System.Data.SqlDbType.UniqueIdentifier);sqlparm.Value = idomainevent.AggregationRootId;cmd =new SqlCommand("select count(*) from DomainCommandAndEventObject where AggregationRootId=@AggregationRootId", conn);cmd.Parameters.Add(sqlparm);var count = cmd.ExecuteScalar();if(count!=null){domaineventobject.Version = int.Parse(count.ToString());}SqlParameter[] sqlparams = new SqlParameter[7];sqlparams[0] = new SqlParameter("@Id", System.Data.SqlDbType.UniqueIdentifier);sqlparams[0].Value = domaineventobject.Id;sqlparams[1] = new SqlParameter("@AggregationRootId", System.Data.SqlDbType.UniqueIdentifier);sqlparams[1].Value = domaineventobject.AggregationRootId;sqlparams[2] = new SqlParameter("@AssemblyQualifiedAggreateRooType", System.Data.SqlDbType.NVarChar);sqlparams[2].Value = domaineventobject.AssemblyQualifiedAggreateRooType;sqlparams[3] = new SqlParameter("@AssemblyQualifiedCommandAndEventType", System.Data.SqlDbType.NVarChar);sqlparams[3].Value = domaineventobject.AssemblyQualifiedCommandAndEventType;sqlparams[4] = new SqlParameter("@CreateDate", System.Data.SqlDbType.DateTime);sqlparams[4].Value = domaineventobject.CreateDate;sqlparams[5] = new SqlParameter("@Version", System.Data.SqlDbType.Int);sqlparams[5].Value = domaineventobject.Version;sqlparams[6] = new SqlParameter("@Data", System.Data.SqlDbType.VarBinary);sqlparams[6].Value = domaineventobject.Data;cmd = new SqlCommand("insert DomainCommandAndEventObject values(@Id,@AggregationRootId,@AssemblyQualifiedAggreateRooType,@AssemblyQualifiedCommandAndEventType,@CreateDate,@Version,@Data)", conn);foreach(var sqlparam in sqlparams){cmd.Parameters.Add(sqlparam);}cmd.ExecuteNonQuery();}catch(Exception error){throw error;}finally{cmd.Dispose();conn.Close();}

这样,我们基本就实现了事件与存储方面的基础内容。

QQ讨论群:309287205
微服务实战视频请关注微信公众号:MSSHCJ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389761.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时间序列数据的多元回归_清理和理解多元时间序列数据

时间序列数据的多元回归No matter what kind of data science project one is assigned to, making sense of the dataset and cleaning it always critical for success. The first step is to understand the data using exploratory data analysis (EDA)as it helps us crea…

vue-cli搭建项目的目录结构及说明

vue-cli基于webpack搭建项目的目录结构 build文件夹 ├── build // 项目构建的(webpack)相关代码 │ ├── build.js // 生产环境构建代码(在npm run build的时候会用到这个文件夹)│ ├── check-versions.js // 检查node&am…

391. 完美矩形

391. 完美矩形 给你一个数组 rectangles ,其中 rectangles[i] [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) ,右上顶点是 (ai, bi) 。 如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否…

bigquery 教程_bigquery挑战实验室教程从数据中获取见解

bigquery 教程This medium article focusses on the detailed walkthrough of the steps I took to solve the challenge lab of the Insights from Data with BigQuery Skill Badge on the Google Cloud Platform (Qwiklabs). I got access to this lab in the Google Cloud R…

学习linux系统到底有没捷径?

2019独角兽企业重金招聘Python工程师标准>>> 说起linux操作系,可能对于很多不了解的人来说,第一个想到的就是类似于黑客帝国中的黑框框以及一串串不知所云的代码,总之这些感觉都可以总结成为一个字,那就是——酷&#…

wxpython实现界面跳转

wxPython实现Frame之间的跳转/更新的一种方法 wxPython是Python中重要的GUI框架,下面通过自己的方法实现模拟类似PC版微信登录,并跳转到主界面(朋友圈)的流程。 (一)项目目录 【说明】 icon : 保存项目使用…

java职业技能了解精通_如何通过精通数字分析来提升职业生涯的发展,第8部分...

java职业技能了解精通Continuing from the seventh article in this series, we are going to explore ways to present data. Over the past few years, Marketing and SEO field has become more data-driven than in the past thanks to tools like Google Webmaster Tools …

kfc流程管理炸薯条几秒_炸薯条成为数据科学的最后前沿

kfc流程管理炸薯条几秒In February, our Data Science team had an argument about which restaurant we went to made the best French Fry.2月,我们的数据科学团队对我们去哪家餐厅做得最好的炸薯条产生了争议。 We decided to make it a competition throughout…

bigquery_到Google bigquery的sql查询模板,它将您的报告提升到另一个层次

bigqueryIn this post, we’re sharing report templates that you can build with SQL queries to Google BigQuery data.在本文中,我们将分享您可以使用SQL查询为Google BigQuery数据构建的报告模板。 First, you’ll find out about what you can calculate wit…

分类树/装袋法/随机森林算法的R语言实现

原文首发于简书于[2018.06.12] 本文是我自己动手用R语言写的实现分类树的代码,以及在此基础上写的袋装法(bagging)和随机森林(random forest)的算法实现。全文的结构是: 分类树 基本知识predginisplitrules…

数据科学学习心得_学习数据科学时如何保持动力

数据科学学习心得When trying to learn anything all by yourself, it is easy to lose motivation and get thrown off track.尝试自己学习所有东西时,很容易失去动力并偏离轨道。 In this article, I will provide you with some tips that I used to stay focus…

用php当作cat使用

今天,本来是想敲 node test.js 执行一下,test.js文件,结果 惯性的敲成了 php test.js, 原文输出了 test.js的内容。 突然觉得,这东西 感觉好像是 cat 命令,嘿嘿,以后要是ubuntu 上没装 cat , …

建信01. 间隔删除链表结点

建信01. 间隔删除链表结点 给你一个链表的头结点 head,每隔一个结点删除另一个结点(要求保留头结点)。 请返回最终链表的头结点。 示例 1: 输入:head [1,2,3,4] 输出: [1,3] 解释: 蓝色结点为删除的结点…

python多项式回归_在python中实现多项式回归

python多项式回归Video Link影片连结 You can view the code used in this Episode here: SampleCode您可以在此处查看 此剧 集中使用的代码: SampleCode 导入我们的数据 (Importing our Data) The first step is to import our data into python.第一步是将我们的…

Uboot 命令是如何被使用的?

有什么问题请 发邮件至syyxyoutlook.com, 欢迎交流~ 在uboot代码中命令的模式是这个样子: 这样是如何和命令行交互的呢? 在command.h 中, 我们可以看到如下宏定义 将其拆分出来: #define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \ U_…

大数据可视化应用_在数据可视化中应用种族平等意识

大数据可视化应用The following post is a summarized version of the article accepted to the 2020 Visualization for Communication workshop as part of the 2020 IEEE VIS conference to be held in October 2020. The full paper has been published as an OSF Preprint…

Windows10电脑系统时间校准

有时候新安装电脑系统,系统时间不对,需要主动去校准系统时间。1、点击时间 2、日期和时间设置 3、其他日期、时间和区域设置 4、设置时间和日期 5、Internet 时间 6、点击立即更新,如果更新失败就查电脑是否已联网,重试点击立即更…

pd种知道每个数据的类型_每个数据科学家都应该知道的5个概念

pd种知道每个数据的类型意见 (Opinion) 目录 (Table of Contents) Introduction 介绍 Multicollinearity 多重共线性 One-Hot Encoding 一站式编码 Sampling 采样 Error Metrics 错误指标 Storytelling 评书 Summary 摘要 介绍 (Introduction) I have written about common ski…

xgboost keras_用catboost lgbm xgboost和keras预测财务交易

xgboost kerasThe goal of this challenge is to predict whether a customer will make a transaction (“target” 1) or not (“target” 0). For that, we get a data set of 200 incognito variables and our submission is judged based on the Area Under Receiver Op…

2017. 网格游戏

2017. 网格游戏 给你一个下标从 0 开始的二维数组 grid ,数组大小为 2 x n ,其中 grid[r][c] 表示矩阵中 (r, c) 位置上的点数。现在有两个机器人正在矩阵上参与一场游戏。 两个机器人初始位置都是 (0, 0) ,目标位置是 (1, n-1) 。每个机器…