.NET Core开发实战(第26课:工程结构概览:定义应用分层及依赖关系)--学习笔记...
26 | 工程結構概覽:定義應用分層及依賴關系
從這一節開始進入微服務實戰部分
這一節主要講解工程的結構和應用的分層
在應用的分層這里定義了四個層次:
1、領域模型層
2、基礎設施層
3、應用層
4、共享層
可以通過代碼來看一下
源碼鏈接:
https://github.com/witskeeper/geektime/tree/master/microservices
共享層一共建立三個工程:
1、GeekTime.Core:主要承載基礎的簡單的類型,比如說異常或者一些幫助類
2、GeekTime.Domain.Abstractions:抽象層,領域的抽象是指在領域模型可以定義一些基類或者接口,領域事件接口,領域事件處理接口,還有 Entity 的接口和 Entity 的基類
3、GeekTime.Infrastructure.Core:基礎設施的核心層,是指對倉儲,還有 EFContext 定義一些共享代碼
這些包實際上在不同的項目里面都可以共享,所以建議的做法是把這些代碼都通過私有的 NuGet 的倉庫來存儲,然后其他的工程可以使用 NuGet 包來直接引用即可
領域模型層就是定義領域模型的地方,這里面會有不同的聚合,還有領域事件,不同的聚合下面就是領域模型
基礎設施層是倉儲層和一些共享代碼的實現,這里只定義了倉儲層的實現,包括 EF 的 DomainContext,還有 Order 的倉儲層,User 的倉儲層,還定義了領域模型與數據庫之間的映射關系,就是在 EntityConfigurations 這目錄下面去定義
應用層分兩個,一個工程是 API 層,是用來承載 Web API 或者 Web 應用的,另外一個是后臺任務,這個就是用來執行一些特殊的 Job,作為 Job 的宿主運行的,它可以是一個控制臺的應用程序
在 Web 層,Web API 層,也分了幾個關鍵目錄 Application,Controllers,Extensions,Infrastructure
基礎設施層會放一些身份認證緩存之類的與基礎設施交互相關的一些代碼
擴展層主要是將服務注冊進容器的代碼和中間件配置的代碼,也就是兩擴展方法,一個是對 ServiceCollection 的擴展,一個是對 ApplicationBuilder 的擴展
控制器層主要用來定義 Web API,這一層就是定義前后端交互的接口
應用層使用了 CQRS 的設計模式,就是命令與查詢職責分離,把命令放在一個目錄,把查詢放在一個目錄,同樣的這里還有兩個事件處理的目錄,一個是領域模型,領域事件的處理,一個是集成事件的處理
再看一下各層之間的依賴關系
Shared 層實際上是不依賴任何層次的,它存儲了共享的代碼,被各個工程共享
GeekTime.Core,GeekTime.Domain.Abstractions 是不依賴任何工程的,而 GeekTime.Infrastructure.Core 依賴了 GeekTime.Domain.Abstractions,實現了倉儲,比如說倉儲會依賴 IAggregateRoot 接口
public interface IRepository<TEntity> where TEntity : Entity, IAggregateRoot領域模型需要繼承模型的基類,并且實現一個聚合根的接口,表示它是一個聚合根
public class Order : Entity<long>, IAggregateRoot領域事件需要實現一個領域事件的接口
public class OrderCreatedDomainEvent : IDomainEvent基礎設施層是一個獨立的程序集,實現了倉儲的部分,定義了一個 Order 的倉儲
public interface IOrderRepository : IRepository<Order, long>還定義了 Order 倉儲的實現
public class OrderRepository : Repository<Order, long, DomainContext>, IOrderRepository {public OrderRepository(DomainContext context) : base(context){} }這里可以看到倉儲實際上依賴了基礎設施層共享代碼里面的倉儲的定義 IRepository,這樣就可以復用倉儲層的代碼,這樣定義 OrderRepository 就會比較簡單,可以復用 Repository 的一些實現
public abstract class Repository<TEntity, TKey, TDbContext> : Repository<TEntity, TDbContext>, IRepository<TEntity, TKey> where TEntity : Entity<TKey>, IAggregateRoot where TDbContext : EFContext {public Repository(TDbContext context) : base(context){}public virtual bool Delete(TKey id){var entity = DbContext.Find<TEntity>(id);if (entity == null){return false;}DbContext.Remove(entity);return true;}public virtual async Task<bool> DeleteAsync(TKey id, CancellationToken cancellationToken = default){var entity = await DbContext.FindAsync<TEntity>(id, cancellationToken);if (entity == null){return false;}DbContext.Remove(entity);return true;}public virtual TEntity Get(TKey id){return DbContext.Find<TEntity>(id);}public virtual async Task<TEntity> GetAsync(TKey id, CancellationToken cancellationToken = default){return await DbContext.FindAsync<TEntity>(id, cancellationToken);} }已經實現了一些基本的方法,增刪改查的方法
數據庫訪問的實現,繼承了自己定義的 EFContext,EFContext 作為共享代碼在各個工程里面復用
public class DomainContext : EFContext另外一個比較特殊的是事務處理的對象,這個對象是用來管理整個應用程序的請求上下文中的事務,這樣就可以避免手動地去處理事務,簡化代碼
public class DomainContextTransactionBehavior<TRequest, TResponse> : TransactionBehavior<DomainContext, TRequest, TResponse> {public DomainContextTransactionBehavior(DomainContext dbContext, ICapPublisher capBus, ILogger<DomainContextTransactionBehavior<TRequest, TResponse>> logger) : base(dbContext, capBus, logger){} }應用層依賴了基礎設施層,基礎設施層又依賴了領域層
應用層實際上是把各層組裝在一起的這一層,它是應用程序的一個宿主,協調各層之間的關系,以及組裝代碼都是在這里實現的
總結一下
領域模型層專注于業務的設計,它不依賴于其他各層,它是相對獨立的
基礎設施的倉儲層僅僅負責領域模型的存取,它不負責任何的業務邏輯代碼的承載
推薦使用 CQRS 的模式來設計應用程序,使應用程序的代碼結構更加的合理,在團隊和項目膨脹的情況下,工程的可維護性不至于急劇的下降
Web API 是面向前端交互的接口,避免依賴領域模型
共享代碼建議設計為共享包,使用私有的 NuGet 倉庫來分發和管理
總結
以上是生活随笔為你收集整理的.NET Core开发实战(第26课:工程结构概览:定义应用分层及依赖关系)--学习笔记...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玩转控件:重写/重绘Dev中Messag
- 下一篇: 聊聊面试的事(应聘方)