0

我正在實現一種使用單個數據存儲但分開查詢和命令模型的CQRS形式。對於我正在實施DDD的命令方面,包括存儲庫,IoC和依賴注入。對於查詢方面,我使用here所述的Finder模式。基本上,查找器類似於存儲庫,但僅限於查找方法。CQRS - 接口和依賴注入是否需要讀取模型?

因此,在我的應用程序中,在我的DAL中,我使用ADO.net和原始SQL來執行我的查詢。 ADO.Net的東西都被抽象成一個漂亮的幫助器類,這樣我的Finder類就可以簡單地將查詢傳遞給ADO幫助器,該幫助器返回查找器/映射器類轉換爲讀取模型的通用數據對象。

當前,Finder方法(如我的命令存儲庫)通過注入到我的控制器的接口進行訪問,但我想知道接口,DI和IoC是否對查詢方過度殺手,因爲我已經閱讀了有關CQRS的閱讀方建議使用「瘦數據層」。

爲什麼不直接訪問我的Finders?我理解接口和DI的論點。即分離關注點和可測試性。在SOC的情況下,我的DAL已經通過使用映射器類並將ADO.net內容放入輔助類中分離出數據庫特定的邏輯。就測試而言,根據this question單元測試讀取模型不是必需的。

public class PersonController : Controller 
{ 

    private IPersonFinder _person; 

    public PersonController(IPersonFinder person) 
    { 
     _person = person; 
    } 

    public ActionResult Details(int id) 
    { 
     Person person = _person.GetByID(id); 

     // TODO: Map person to viewmodel 


     return this.View(viewmodel); 
    } 

} 
+0

但是如果你想將一些橫切關注點應用到你的'PersonFinder'上呢?當你將它應用到靜態類時,這將是非常困難的(和很多重複的代碼),而如果一個接口被注入,你可以自由地用裝飾器,代理,攔截器或其他任何模式來包裝該實例在你的工具箱中。 – Steven

回答

2

是否使用 IOC和DI:

因此,在總結,讀模式,我能做到這一點:

public class PersonController : Controller 
{ 
    public ActionResult Details(int id) 
    { 

     var person = new Person(); 
     person = PersonFinder.GetByID(id); 

     // TODO: Map person to viewmodel 


     return this.View(viewmodel); 
    } 

} 

相反的呢?這是不好的屁股!無論如何,第二個版本更好,因爲它不依賴於靜態類。使用靜態會打開潘多拉盒子,不要這樣做,因爲所有使用靜態的原因是不好的。

你真的沒有得到任何好處,使用靜態類,一旦你已經使用DI容器,沒有額外的成本。你直接使用Finders,但你讓DI容器實例化一個而不是你調用一個靜態對象。

更新

薄讀出層指的是使用簡化的模型讀代替富域對象。它與DI無關,無論查詢服務是如何構建的或由誰來建立都無關緊要,重要的是不要將業務對象包含在查詢中。

+0

是的,你對靜態類的事情是正確的,我的錯誤。我將編輯問題以在控制器方法內實例化類。我的擔憂仍然是,通過在讀取模型中使用DI,我正在擺脫閱讀模型的薄數據層的概念。 –

+0

您的閱讀模型是DTO。您正在使用DI來保持事物解耦,與讀取模型無關。瘦數據層是關於讓查詢服務直接使用簡化模型而不是複雜的複雜模型。不要過分堅持這一點,並保持你的DI容器。 – MikeSW

+0

我的解釋是保持整個過程,即從數據庫獲取數據並將其顯示在屏幕上。你是否建議我應該更加狹隘地看待這個問題,並專心致力於保持查詢方面的優勢並填充我的dtos? –

1

讀/寫分離與編碼技術如依賴注入完全無關。您閱讀的模型比以前的組合讀/寫模型服務的用途更少。你可以考慮拋棄所有的服務器端代碼,只使用數據庫的本地REST API嗎?你可以連線你的控制器直接用SQL查詢數據庫並將數據作爲JSON返回?你需要一個通用的類庫來處理特定的讀請求嗎?

+0

我的觀點是,像依賴注入這樣的東西會增加架構開銷。因此,讀和寫的分離與編碼技術有關,因爲建議讀模型保持精簡。 –