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