原文链接: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

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

  1. 基于事件驱动架构构建微服务第1部分:应用程序特定的业务规则

    原文链接:https://logcorner.com/building-microservices-through-event-driven-architecture-part1-applicatio ...

  2. 基于事件驱动架构构建微服务第8部分:在应用程序上实现事件溯源

    原文链接:https://logcorner.com/building-microservices-through-event-driven-architecture-part8-implementi ...

  3. 基于事件驱动架构构建微服务第16部分:Azure Active Directory B2C

    原文链接: https://logcorner.com/building-micro-services-through-event-driven-architecture-part16-azure-a ...

  4. 基于事件驱动架构构建微服务第14部分:查询API

    原文链接:https://logcorner.com/building-micro-services-through-event-driven-architecture-part14-query-ap ...

  5. 基于事件驱动架构构建微服务第11部分:持续集成

    原文链接:https://logcorner.com/building-microservices-through-event-driven-architecture-part12-continuou ...

  6. 基于事件驱动架构构建微服务第10部分:在docker容器内运行单元测试

    原文链接:https://logcorner.com/building-microservices-through-event-driven-architecture-part11-run-unit- ...

  7. 基于事件驱动架构构建微服务第13部分:使用来自Apache KAFKA的事件并将投影流传输到ElasticSearch...

    原文链接:https://logcorner.com/building-microservices-through-event-driven-architecture-part13-read-mode ...

  8. 基于事件驱动架构构建微服务第2部分:领域对象和业务规则

    原文链接:https://logcorner.com/building-microservices-through-event-driven-architecture-part2-domain-obj ...

  9. 基于事件驱动架构构建微服务第19部分:使用 SignalR 和 Azure Active Directory 构建和保护实时通信...

    原文链接:https://logcorner.com/building-micro-services-through-event-driven-architecture-part19-building ...

最新文章

  1. 讯飞智慧餐厅(安徽赛区)比赛通知
  2. SqlServer索引的原理与应用
  3. beego-安装(window版)
  4. 【嵌入式】ARM技术博客汇总
  5. 海量日志分析方案--logstash+kibnana+kafka
  6. cocos2d-x游戏实例(26)-简易动作游戏(4)
  7. Python实战——2048
  8. C语言的常用字符串操作函数(一)
  9. mac git 冲突工具
  10. android 画圆角背景颜色,android圆角矩形有背景颜色
  11. python找电影资源_python一键电影搜索与下载
  12. 神舟飞天,与有荣焉!麒麟信安操作系统筑牢神舟十四号发射软件基石!
  13. python 类 对象 知乎_Python 基础入门(八)类与对象 学习小结
  14. php做一个文章页面,thinkphp教程-文章内容页上一页下一页功能实现
  15. 没有人比我更懂牛排……吧?
  16. windows那些讨厌的CPU占用进程
  17. 整理下使用yum localinstall做离线安装的点
  18. angular aot编译报错 ERROR in ./src/main.ts 解决方法
  19. php摇号 中标 程序,摇号信息系统招标公告
  20. 如何修改wordpress的访问端口

热门文章

  1. URL 路径长度限制(错误:指定的文件或文件夹名称太长)
  2. Linux主机名那点事儿
  3. matlab 规范,matlab-代码-规范
  4. html 跳转到本页面指定位置
  5. mysql中查询一个字段属于哪一个数据库中的哪一个表的方式
  6. C++学习笔记(二)——交换函数(swap)
  7. IIS应用程序池相关问题及连接池已满的解决方法
  8. Teams Bot库的JSON
  9. 如何在PowerPoint演示文稿中使用iTunes音乐
  10. 荣耀9igoogle模式_iGoogle个性化主页的6种替代方法