日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

结合eShopOnWeb全面认识领域模型架构

發布時間:2023/12/4 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 结合eShopOnWeb全面认识领域模型架构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

.項目分析

  在上篇中介紹了什么是"干凈架構",DDD符合了這種干凈架構的特點,重點描述了DDD架構遵循的依賴倒置原則,使軟件達到了低藕合。eShopOnWeb項目是學習DDD領域模型架構的一個很好案例,本篇繼續分析該項目各層的職責功能,主要掌握ApplicationCore領域層內部的術語、成員職責。

  1. web層介紹

    eShopOnWeb項目與Equinox項目,雙方在表現層方面對比,沒有太大區別。都是遵循了DDD表現層的功能職責。有一點差異的是eShopOnWeb把表現層和應用服務層集中在了項目web層下,這并不影響DDD風格架構。

    項目web表現層引用了ApplicationCore領域層和Infrastructure基礎設施層,這種引用依賴是正常的。引用Infrastructure層是為了添加EF上下文以及Identity用戶管理。?引用ApplicationCore層是為了應用程序服務?調用?領域服務處理領域業務。

    在DDD架構下依賴關系重點強調的是領域層的獨立,領域層是同心圓中最核心的層,所以在eShopOnWeb項目中,ApplicationCore層并沒有依賴引用項目其它層。再回頭看Equinox項目,領域層也不需要依賴引用項目其它層。

    下面web混合了MVC和Razor,結構目錄如下所示:

    (1) Health checks 

      Health checks是ASP.NET Core的特性,用于可視化web應用程序的狀態,以便開發人員可以確定應用程序是否健康。運行狀況檢查端點/health。

//添加服務
services.AddHealthChecks()
.AddCheck
<HomePageHealthCheck>("home_page_health_check")
.AddCheck
<ApiHealthCheck>("api_health_check");
 
//添加中間件
   app.UseHealthChecks("/health");

      ?下圖檢查了web首頁和api接口的健康狀態,如下圖所示

    (2) Extensions

      向現有對象添加輔助方法。該Extensions文件夾有兩個類,包含用于電子郵件發送和URL生成的擴展方法。

    (3) 緩存

      對于Web層獲取數據庫的數據,如果數據不會經常更改,可以使用緩存,避免每次請求頁面時,都去讀取數據庫數據。這里用的是本機內存緩存。

//緩存接口類
private readonly IMemoryCache _cache;
// 添加服務,緩存類實現
services.AddScoped<ICatalogViewModelService, CachedCatalogViewModelService>();
//添加服務,非緩存的實現
//services.AddScoped<ICatalogViewModelService, CatalogViewModelService>();
  2. ApplicationCore

    ApplicationCore是領域層,是項目中最重要最復雜的一層。ApplicationCore層包含應用程序的業務邏輯,此業務邏輯包含在領域模型中。領域層知識在Equinox項目中并沒有講清楚,這里在重點解析領域層內部成員,并結合項目來說清楚。

    下面講解領域層內部的成員職責描述定義,參考了“Microsoft.NET企業級應用架構設計 第二版”。

    領域層內部包括:領域模型和領域服務二大塊。涉及到的術語:

? ? ? ? ? ? ? ? ? ?  領域模型(模型)

         ?   1)模塊

?????????????????  ?     2)領域實體(也叫"實體")

?????????????????  ?     3)值對象

?????????????????  ?     4)聚合

?????????????????  ? 領域服務(也叫"服務")

?????????????????  ? 倉儲

    下面是領域層主要的成員:

    下面是聚合與領域模型的關系。最終領域模型包含了:聚合、單個實體、值對象的結合。

    (1) 領域模型

      領域模型是提供業務領域的概念視圖,它由實體和值對象構成。在下圖中Entities文件夾是領域模型,可以看到包含了聚合、實體、值對象。

      1.1 模塊

   模塊是用來組織領域模型,在.net中領域模型通過命令空間組織,模塊也就是命名空間,用來組織類庫項目里的類。比如:

namespace Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate
namespace Microsoft.eShopWeb.ApplicationCore.Entities.BuyerAggregate

      1.2 實體

  實體通常由數據和行為構成。如果要在整個生命周期的上下文里唯一跟蹤它,這個對象就需要一個身份標識(ID主鍵),并看成實體。 如下所示是一個實體: 

/// <summary>
/// 領域實體都有唯一標識,這里用ID做唯一標識
/// </summary>
public class BaseEntity
{
public int Id { get; set; }
}

/// <summary>
/// 領域實體,該實體行為由Basket聚合根來操作
/// </summary>
public class BasketItem : BaseEntity
{
public decimal UnitPrice { get; set; }
public int Quantity { get; set; }
public int CatalogItemId { get; set; }
}

?  1.3 值對象

  值對象和實體都由.net 類構成。值對象是包含數據的類,沒有行為,可能有方法本質上是輔助方法。值對象不需要身份標識,因為它們不會改變狀態。如下所示是一個值對象


  

1.4 聚合

  在開發中單個實體總是互相引用,聚合的作用是把相關邏輯的實體組合當作一個整體對待。聚合是一致性(事務性)的邊界,對領域模型進行分組和隔離。聚合是關聯的對象(實體)群,放在一個聚合容器中,用于數據更改的目的。每個聚合通常被限制于2~3個對象。聚合根在整個領域模型都可見,而且可以直接引用。   

    在該項目中領域模型與“Microsoft.NET企業級應用架構設計第二版”書中描述的職責有不一樣地方,來看一下:

   (1) 領域服務有直接引用聚合中的實體(如:BasketItem)。書中描述是聚合中實體不能從聚合之處直接引用,應用把聚合看成一個整體。

   (2) 領域實體幾乎都是貧血模型。書中描述是領域實體應該包括行為和數據。

  (2) 領域服務

   領域服務類方法實現領域邏輯,不屬于特定聚合中(聚合是屬于領域模型的),很可能跨多個實體。當一塊業務邏輯無法融入任何現有聚合,而聚合又無法通過重新設計適應操作時,就需要考慮使用領域服務。下圖是領域服務文件夾:


      在該項目與“Microsoft.NET企業級應用架構設計第二版”書中描述的領域服務職責不完全一樣,來看一下:

      (1) 項目中,領域服務只是用來執行領域業務邏輯,包括了訂單服務OrderService和購物車服務BasketService。書中描述是可能跨多個實體。當一塊業務邏輯無法融入任何現有聚合。


     總的來說,eShopOnWeb項目雖然沒有完全遵循領域層中,成員職責描述,但可以理解是在代碼上簡化了領域層的復雜性。

?    (3) 倉儲

      倉儲是協調領域模型和數據映射層的組件。倉儲是領域服務中最常見類型,它負責持久化。倉儲接口的實現屬于基礎設施層。倉儲通常基于一個IRepository接口。 下面看下項目定義的倉儲接口。

/// <summary>
/// T是領域實體,是BaseEntity類型的實體
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IAsyncRepository<T> where T : BaseEntity
{
Task
<T> GetByIdAsync(int id);
Task
<IReadOnlyList<T>> ListAllAsync();
//使用領域規則查詢
Task<IReadOnlyList<T>> ListAsync(ISpecification<T> spec);
Task
<T> AddAsync(T entity);
Task UpdateAsync(T entity);
Task DeleteAsync(T entity);
//使用領域規則查詢
Task<int> CountAsync(ISpecification<T> spec);
}

    (4) 領域規則

      在倉儲設計查詢接口時,可能還會用到領域規則。 在倉儲中一般都是定義固定的查詢接口,如上面倉儲的IAsyncRepository所示。而復雜的查詢條件可能需要用到領域規則。在本項目中通過強大Linq 表達式樹Expression?來實現動態查詢。


?    最后Interfaces文件夾中定義的接口,都由基礎設施層來實現。如:

????????     IAppLogger日志接口

????????     IEmailSender郵件接口

???????    ? IAsyncRepository倉儲接口

  3.Infrastructure層

    基礎設施層Infrastructure依賴于ApplicationCore,這遵循依賴倒置原則(DIP),Infrastructure中代碼實現了ApplicationCore中定義的接口(Interfaces文件夾)。該層沒有太多要講的,功能主要包括:使用EF Core進行數據訪問、Identity、日志、郵件發送。與Equinox項目的基礎設施層差不多,區別多了領域規則。

    ? ? ? ?領域規則SpecificationEvaluator.cs類用來構建查詢表達式(Linq expression),該類返回IQueryable<T>類型。IQueryable接口并不負責查詢的實際執行,它所做的只是描述要執行的查詢。


 參考資料

    Microsoft.NET企業級應用架構設計 第二版

原文地址:https://www.cnblogs.com/MrHSR/p/10869911.html

.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總?http://www.csharpkit.com?


總結

以上是生活随笔為你收集整理的结合eShopOnWeb全面认识领域模型架构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。