基于事件驱动架构构建微服务第4部分:repositories
原文鏈接:https://logcorner.com/building-microservices-through-event-driven-architecture-part4-repositories/
在本文中,我將實(shí)現(xiàn)Repositories的命令端。存儲(chǔ)庫屬于Clean架構(gòu)的接口適配器
在這一步中,我將開始實(shí)現(xiàn)基礎(chǔ)設(shè)施的命令端,我將專注于如何持久化數(shù)據(jù)。
我將使用EntityFrameworkCore和SQL Server。
因?yàn)長ogCorner.EduSync.Speech.Application.UseCases使用ISpeechRepository作為依賴項(xiàng),我認(rèn)為最明顯的方法是從實(shí)現(xiàn)ISpeechRepository開始,然后繼續(xù)實(shí)現(xiàn)它的依賴項(xiàng)等......但既然我知道我要去哪里,我將按以下步驟進(jìn)行:
UnitOfWork:我將使用UnitOfWork模式,它將幫助我將AggregateRoot視為一個(gè)用于數(shù)據(jù)更改的單元。
存儲(chǔ)庫:我將使用存儲(chǔ)庫模式,AggregateRoots是我的代碼從存儲(chǔ)庫加載的唯一對(duì)象 讓我們創(chuàng)建一個(gè)通用存儲(chǔ)庫IRepository并應(yīng)用AggregateRoot約束。
我的IRepository如下所示:
T是一個(gè)AggregateRoot并且TIdentifier是AggregateRoot主鍵的類型:int、Guid等等……
ISpeechRepository實(shí)現(xiàn)了IRepository<Speech, Guid>,其中Speech是 AggregateRoot,Guid是Speech.Id的類型
無法為非AggregateRoot實(shí)體創(chuàng)建存儲(chǔ)庫:例如MediaFile
IUnitOfWork.Commit持久化(保存或更新)整個(gè)聚合(AggregateRoot和相關(guān)實(shí)體)
UNITOFWORK
讓我們從測試IUnitOfWork開始,它將導(dǎo)致UnitOfWork的實(shí)現(xiàn)。后者將需要一個(gè)從 DbContext繼承的類。(在我的情況下是 DataBaseContext)
測試1:保存時(shí),IUnitOfWork.Commit應(yīng)該保存聚合根并且DbContext.SaveChanges只調(diào)用一次
UnitOfWork的實(shí)現(xiàn)
讓我們創(chuàng)建一個(gè)繼承自DbContext的DataBaseContext類
UnitOfWork第一次測試的最終實(shí)現(xiàn)
實(shí)現(xiàn)UnitOfWork.Dispose
測試2:disposing時(shí),unitOfWork.Dispose只調(diào)用一次
讓我們實(shí)現(xiàn)UnitOfWork.Dispose()
在此階段,解決方案編譯通過,所有測試均通過,LogCorner.EduSync.Speech.Infrastructure的代碼覆蓋率為100%
REPOSITORY
測試3:驗(yàn)證CreateAsync可以在Repository上調(diào)用并且應(yīng)該觸發(fā)dbset.AddAsync
Repository只能用AggregateRoot實(shí)例化,所以讓我們創(chuàng)建一個(gè)繼承自 AggregateRoot的類進(jìn)行測試。
Repository的最終實(shí)現(xiàn)將如下所示
SPEECHREPOSITORY
測試4:驗(yàn)證是否可以在SpeechRepository上調(diào)用CreateAsync并僅觸發(fā)Repository.CreateAsync一次
這個(gè)測試的目標(biāo)是實(shí)現(xiàn)SpeechRepository,所以我驗(yàn)證當(dāng)SpeechRepository.CreateAsync 被調(diào)用時(shí),Repository.CreateAsync只被調(diào)用一次
這是SpeechRepository的最終實(shí)現(xiàn)
MAPPING
本節(jié)的實(shí)現(xiàn)因使用的ORM(EF、NHibernate或其他)而異。例如,我們可以創(chuàng)建特定于存儲(chǔ)庫(SpeechDao)的類并應(yīng)用SpeechDao和Speech之間的映射。SpeechDao可以看作是領(lǐng)域的Speech類的重復(fù)類(屬性)。
但是,EF可以通過提供IEntityTypeConfiguration接口,而無需創(chuàng)建存儲(chǔ)庫特定的類,然后在重復(fù)的類之間應(yīng)用映射。
我可以使用它來將領(lǐng)域?qū)ο笾赶驍?shù)據(jù)庫表,而無需在SpeechDao和Speech之間應(yīng)用額外的映射,如下所示:
我們可以注意到,ValueObjects是如何管理的
您需要知道的最后一件事是EFCore需要一個(gè)無參數(shù)構(gòu)造函數(shù),因?yàn)樗褂梅瓷鋪硗瓿伤墓ぷ鳌?/p>
如果您不想更新領(lǐng)域類并引入私有無參數(shù)構(gòu)造函數(shù),則應(yīng)創(chuàng)建存儲(chǔ)庫特定類,然后在重復(fù)類之間應(yīng)用映射。這個(gè)存儲(chǔ)庫特定的類應(yīng)該有無參數(shù)的構(gòu)造函數(shù)。
DATABASE
我使用 SSDT設(shè)計(jì)了Sql Server數(shù)據(jù)庫,這將有助于我的devops管道
CONFIGURE
配置 LogCorner.EduSync.Speech.Presentation以定位sql數(shù)據(jù)庫
最后,完成依賴注入的配置
API測試
現(xiàn)在可以使用postman測試整個(gè)應(yīng)用程序
歡迎關(guān)注我的個(gè)人公眾號(hào)”My IO“
總結(jié)
以上是生活随笔為你收集整理的基于事件驱动架构构建微服务第4部分:repositories的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试官:实现一个带值变更通知能力的Dic
- 下一篇: dotnet 基于 dotnet for