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