基于事件驱动架构构建微服务第4部分:repositories

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于事件驱动架构构建微服务第4部分:repositories相关的知识,希望对你有一定的参考价值。

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

在本文中,我将实现Repositories的命令端。存储库属于Clean架构的接口适配器

在这一步中,我将开始实现基础设施的命令端,我将专注于如何持久化数据。

我将使用EntityFrameworkCore和SQL Server。

因为LogCorner.EduSync.Speech.Application.UseCases使用ISpeechRepository作为依赖项,我认为最明显的方法是从实现ISpeechRepository开始,然后继续实现它的依赖项等......但既然我知道我要去哪里,我将按以下步骤进行:

  • UnitOfWork:我将使用UnitOfWork模式,它将帮助我将AggregateRoot视为一个用于数据更改的单元。

  • 存储库:我将使用存储库模式,AggregateRoots是我的代码从存储库加载的唯一对象 让我们创建一个通用存储库IRepository并应用AggregateRoot约束。

我的IRepository如下所示:

T是一个AggregateRoot并且TIdentifier是AggregateRoot主键的类型:int、Guid等等……

ISpeechRepository实现了IRepository<Speech, Guid>,其中Speech是 AggregateRoot,Guid是Speech.Id的类型

无法为非AggregateRoot实体创建存储库:例如MediaFile

IUnitOfWork.Commit持久化(保存或更新)整个聚合(AggregateRoot和相关实体)

UNITOFWORK

让我们从测试IUnitOfWork开始,它将导致UnitOfWork的实现。后者将需要一个从 DbContext继承的类。(在我的情况下是 DataBaseContext)

测试1:保存时,IUnitOfWork.Commit应该保存聚合根并且DbContext.SaveChanges只调用一次

UnitOfWork的实现

让我们创建一个继承自DbContext的DataBaseContext类

UnitOfWork第一次测试的最终实现

实现UnitOfWork.Dispose

测试2:disposing时,unitOfWork.Dispose只调用一次

让我们实现UnitOfWork.Dispose()

在此阶段,解决方案编译通过,所有测试均通过,LogCorner.EduSync.Speech.Infrastructure的代码覆盖率为100%

REPOSITORY

测试3:验证CreateAsync可以在Repository上调用并且应该触发dbset.AddAsync

Repository只能用AggregateRoot实例化,所以让我们创建一个继承自 AggregateRoot的类进行测试。

Repository的最终实现将如下所示

SPEECHREPOSITORY

测试4:验证是否可以在SpeechRepository上调用CreateAsync并仅触发Repository.CreateAsync一次

这个测试的目标是实现SpeechRepository,所以我验证当SpeechRepository.CreateAsync 被调用时,Repository.CreateAsync只被调用一次

这是SpeechRepository的最终实现

MAPPING

本节的实现因使用的ORM(EF、NHibernate或其他)而异。例如,我们可以创建特定于存储库(SpeechDao)的类并应用SpeechDao和Speech之间的映射。SpeechDao可以看作是领域的Speech类的重复类(属性)。

但是,EF可以通过提供IEntityTypeConfiguration接口,而无需创建存储库特定的类,然后在重复的类之间应用映射。

我可以使用它来将领域对象指向数据库表,而无需在SpeechDao和Speech之间应用额外的映射,如下所示:

我们可以注意到,ValueObjects是如何管理的

您需要知道的最后一件事是EFCore需要一个无参数构造函数,因为它使用反射来完成它的工作。

如果您不想更新领域类并引入私有无参数构造函数,则应创建存储库特定类,然后在重复类之间应用映射。这个存储库特定的类应该有无参数的构造函数。

DATABASE

我使用 SSDT设计了Sql Server数据库,这将有助于我的devops管道

CONFIGURE

配置 LogCorner.EduSync.Speech.Presentation以定位sql数据库

最后,完成依赖注入的配置

API测试

现在可以使用postman测试整个应用程序

欢迎关注我的个人公众号”My IO“

以上是关于基于事件驱动架构构建微服务第4部分:repositories的主要内容,如果未能解决你的问题,请参考以下文章

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

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

基于事件驱动架构构建微服务第15部分:SPA前端

基于事件驱动架构构建微服务第9部分:处理更新

基于事件驱动架构构建微服务第12部分:向Apache KAFKA生成事件

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