基于事件驱动架构构建微服务第7部分:在仓储上实现事件溯源

原文链接:https://logcorner.com/building-microservices-through-event-driven-architecture-part7-implementing-eventsourcing-on-repositories/

在本文中,我将讨论Repository上的Event Sourcing实现。

仓储负责将事件添加到事件存储并从事件存储中检索所有事件。

保存聚合后,所有与该聚合根相关的未提交事件都会添加到事件存储表中。

eventstore表是一个只能追加的表(不允许更新和删除)。

eventstore表的架构如下所示:

  • Id 主键

  • Version 聚合的版本

  • AggregateId 聚合的标识符

  • Name 事件的名称:2@735f8407-16be-44b5-be96-2bab582b5298

  • TypeName 事件的类型:LogCorner.EduSync.Speech.Domain.Events.Speech.SpeechCreatedEvent、LogCorner.EduSync.Speech.Domain、Version=1.0.0.0、Culture=neutral、PublicKeyToken=null

  • OccurredOn 事件日期

  • PayLoad 事件流:

{
“Title”: { “Value”: “Introducing Azure Cosmos DB” },
“Url”: { “Value”: “https://azure.microsoft.com/en-us/resomurcejjjnns/videos/azure-friday-introducing-azurkke-cosmos-db_g5/” },
“Description”: { “Value”: “Kirill Gavrylyuk stops by Azure Friday to talk Cosmos DB with Scott Hanselman. Watch quick overview of the industry’s first globally distributed multi-model database service followed by a demo of moving an existing MongoDB app to Cosmos DB with a single config change.” },
“Type”: { “Value”: 2 },
“AggregateId”: “735f8407-16be-44b5-be96-2bab582b5298”,
“EventId”: “6eb58cb4-da5e-46d4-8325-e742a20935ab”,
“AggregateVersion”: 0,
“OcurrendOn”: “2019-09-08T10:55:48.5528117Z”
}
  • IsSync 指示事件是否同步的布尔值

要重建聚合的当前状态,我们必须读取与给定聚合ID相关的所有事件,然后调用函数LoadFromHistory。此函数属于AggregateRoot类,应将所有事件应用于聚合。

事件溯源接口

让我们定义IEventStoreRepository接口

  • GetByIdAsync 一个函数,用于从事件存储中检索与聚合相关的所有事件。

  • AppendAsync 一个将事件附加到事件存储的函数

事件溯源实现

让我们定义EventStore类

  • Id 事件流的标识符

  • Version 当前的聚合版本

  • AggregateId 聚合的标识符

  • Name 事件流的名称

  • TypeName 事件的完整类型(例如:LogCorner.EduSync.Speech.Domain.Events.Speech.SpeechCreatedEvent、LogCorner.EduSync.Speech.Domain、Version=1.0.0.0、Culture=neutral、PublicKeyToken=null)

  • OccurredOn 事件发生的日期

  • SerializedBody 事件序列化的JSON

  • AppendAsync 一个函数,用于指示事件是否已同步。

APPENDASYNC 实现

测试用例1:AppendAsync应该在eventstore上附加一个事件:

在这里,我必须模拟一个上下文,创建一个 IEventStoreRepository实例并使用EventStore对象调用AppendAsync,然后上下文应该有一组带有单个元素的 EventStore,并且该元素应该等于我在AppendAsync的参数中传递的eventstore对象.

测试可能如下所示:

但是我将使用entityframeworkcore inmemory数据库而不是使用moq,这是一种更简单的数据库单元测试方法。

所以我可以像这样实例化一个内存上下文:

下一步是创建一个EventStoreRepository类

然后将DbSetEventStore属性添加到DatabaseContex类

代码编译成功但测试失败,因为DbSetEventStore为空。

所以让我们配置一些映射

EventStoreEntityTypeConfiguration类负责将EventStore类映射到EventStore数据库表

最终测试如下所示:

GETBYIDASYNC实现

GetByIdAsync从事件存储中检索与聚合相关的所有事件。

在这里,我必须创建一个Speech类型的空聚合,从与它相关的事件存储中读取所有事件,最后应用这些事件。

测试用例2:AggregateRoot的CreateInstance应该返回一个空的聚合

让我们创建一个Invoker类,负责创建一个空的聚合根

测试通过

测试用例3:GetByIdAsync和BadAggregateId应该引发BadAggregateIdException

给定一个错误的aggregateId(例如:空的aggregateId),GetByIdAsync应该引发一个异常(BadAggregateIdException)

测试用例4:GetByIdAsyncWithNullInstanceOfAggregateShouldRaiseNullInstanceOfAggregateIdException

给定不存在的聚合ID(例如:空聚合 ID),GetByIdAsync应该引发异常 (NullInstanceOfAggregateIdException)

测试用例5:GetByIdAsyncWithoutEventsShouldReturnEmptyList

如果没有与给定聚合ID相关的事件,则GetByIdAsync应返回一个空列表

测试用例6:GetByIdAsyncWithEventsShouldReturnTheCurrentStateOfAggregate

在这里,我必须从事件存储中读取与给定聚合ID相关的所有事件,重建聚合状态并返回它。

为了达到这个目标,我必须根据事件类型反序列化json结构中的事件。

测试用例6.1:反序列化事件流应该返回一个事件

在这里,我将创建一个将json字符串反序列化为Event对象的函数

测试用例6.2:GetByIdAsyncWithEventsShouldReturnTheCurrentStateOfTheAggregate

到这里,我将完成我的函数的实现

本文的源代码可在此处获得 (Feature/Task/EventSourcingRepository)

https://github.com/logcorner/LogCorner.EduSync.Speech.Command/tree/Feature/Task/EventSourcingRepository

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

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

相关文章

python选择题题目_Python接口测试题(持续更新中)

1、json和字典的区别? Json是轻量级的数据交互格式,以key-value的键值对形式来保存数据,结构清晰,可以说是目前互联网项目开发中最常用的一种数据交互格式。 字典,同样是以key-value的键值对来保存数据,是p…

html5 ajax数据显示,html5的ajax学习(二)

一、基础知识点1.ajax可以做事情:局部刷新 浏览器搜索列表记录 加载更多的数据2.登录页面同步网络请求:页面全部刷新,用户量大体验很不好3.ajax的详解:ajax的get和post请求 同步还是异步,true为异步ajax.open("ge…

ISA Server服务器故障恢复一例系统盘符更换之后的应对方法

周四下午的时候,某政府信息中心领导打电话告诉我,ISA Server服务器不能开机了。随后公司的技术员到达现场,经过检查,发现服务器显卡损坏。在更换显卡后,服务器可以开机,但却不能进入系统—-服务器在经过BIO…

扩展Windows Mobile模拟器存储空间的方法

在Windows Mobile应用程序开发的初期,可以使用SDK自带的模拟器来进行调试,这给我们开发人员提供了一种方便的途径。一般的应用程序,占用空间的大小也就几 百K,或者几M,这在模拟器上调试起来一点问题也没有。但是有的时…

UOS LoongArch 上成功安装.NET Core 3.1

龙芯.NET团队正式发布了.NET Core 3.1 For LoongArch, 具体参见龙芯开源网站 http://www.loongnix.cn/index.php/Dotnet 。进入安装包下载地址LoongArch64-.NET Core 3.1,可以看到龙芯.NET团队做了很多工作,为Debian和Redhat两大Linux体系平台都做好了基…

c++ vector拷贝构造_JDK源码分析-Vector

1. 概述上文「JDK源码分析-ArrayList」主要分析了 ArrayList 的实现原理。本文分析 List 接口的另一个实现类:Vector。Vector 的内部实现与 ArrayList 类似,也可以理解为一个「可变数组」。其继承结构如下(省略部分接口)&#xff…

除了PS,原来这个也可以轻松实现图像处理!

全世界只有3.14 % 的人关注了爆炸吧知识在我们生活中,常见的图像处理软件有Adobe Photoshop、Adobe Illustrator等。然而,并非只有软件才能实现图像处理,通过编程手段也是能实现的!今天,小天将要带着大家走进计算机视觉…

下雨天纵使少了什么也是少不了一把伞的,即使是几千年前,也不管细雨霏霏,大雨倾盆。愿意沐浴风雨中,享受这样惠泽的人总是少的。从“孤舟蓑笠翁,独钓寒江雪”,“十里一长亭,五里一短亭”&#xf…

oracle用户名密码过期引起的网站后台无法登录

本来今天休息,但是接到同事反映:客户的WEB无法登录了,网站能打开,但是后台登录不了。我就联系了客户,客户说是WEB用户的密码过期导致的,默认是180天到期。接着就是我的操作流程了:1.先从WEB服务…

微服务的终极目标,Mecha分布式运行时之Dapr

1. Mecha 是啥?微服务发展到今天,已经有很多公司多年前已经改造完毕,也有些公司还在路上,微服务的优势,有过了解的朋友应该也都能说出个一二三来,经历过微服务改造的,应该都知道其中的艰辛。单体…

python input输入多个变量_「Python 秘籍」1.2 解压可迭代对象赋值给多个变量

问题需要从某个可迭代对象中分解出 N 个元素,但是这个可迭代对象的长度可能超过 N,这会导致出现“需要解包的值过多(too many values to unpack)”的异常。解决方案“星号表达式”可以用来解决这个问题。例如,假设开设了一门课程,…

为什么不谈恋爱?

1 存好啦!2 这是我看过最形象的小说描写了图自天秀bot3 原来游泳池是这样建的。。4 这谁还舍得拉绳子啊5 铁笼:大哥,给点面子好不好?6 别说,这门给狗子放头还挺合适的7 机器人骑自行车你点的每个赞,我都认真…

牛!又一顶级大厂开招.NET,5年35k!

继腾讯阿里百度京东华为招.NET Core后,又一顶级大厂开招.NET Core了:美团上海总部,住宿业务线别样红业务部招.NET开发,25~35k,具体参见【招聘(上海)】美团酒店招聘 .NET 高级开发。大厂遥不可及的认知该放下了&#xf…

理科生浪漫起来,谁都顶不住!

全世界只有3.14 % 的人关注了爆炸吧知识和文科常呈现出的诗词歌赋风花雪月不同,理科常常给人一种理性、严肃甚至冰冷的感觉。其实不然,理科中所蕴含的美,非肉眼可窥。在豆瓣话题#理科中的美学#里,我们找到了许多透过数字、显微镜、…

docker 修改阿里镜像源_Jetson Nano 修改源镜像

由于Jeston nano自带的软件源无法更新,因此更换为国内的软件源,本文使用中科大提供的软件源镜像,具体步骤如下:进入Ubuntu系统之后,我们发现使用以下命令,查看ubuntu版本 $ cat /etc/issue 查看Ubuntu系统版…

python中数据用折线图表示_用python处理文本数据

用python处理文本数据Q:这篇文章主要讲什么?A:这篇文章主要讨论如何用python来做一些简单的文本处理——文本相似度比较。谈起python的自然语言处理,肯定会让人想起NLTK。不过上面这两个任务并不需要NLTK这个库&#x…

.Net Core下使用KeyDB高可用缓存集群

前言提到缓存,首先会想到Redis,它是目前最流行的开源内存键值存储服务。使用单个Redis实例进行缓存非常简单,如果创建高可用集群,则需要一个主节点、两个从节点和多个监视主节点的哨兵节点:哨兵节点监控主节点的状态,一…

超赞!世界10个著名悖论的最终解答来了!

全世界只有3.14 % 的人关注了爆炸吧知识今天小编看到一篇作者Das对十大悖论的个人理解,觉得挺有意思,现在便分享给模友们看看,你们的想法是怎样的呢?电车难题引用:“电车难题”是伦理学领域最为知名的思想实验之一&…

设置计算机网络密码怎么设置路由器,如何在计算机上设置路由器密码?

问: 如何在计算机上设置路由器密码?A: 在计算机浏览器中,输入路由器的管理地址,打开登录页面,输入登录密码,然后进入设置页面.然后打开无线设置或Wi-Fi设置选项,您可以设置无线密码(wifi密码). 打开此选项可…

hive sql 怎么实现循环_不出办公室就能无水造纸?让废纸“秒循环再生”怎么实现的...

废纸变为再生纸,不出办公室就能循环利用起来,既节省大量木材,还不消耗一滴水……第三届进博会上,首次参展的打印巨头爱普生带来其全球首创的“干纤维纸张循环系统”,环保效果令人赞叹,吸引大批观众前来围观…