2

我正在開發一個應用程序使用asp.net mvc,NHibernate和DDD。我有我的應用程序的控制器使用的服務層。一切都在使用Unity來注入依賴關係(ISessionFactory存儲庫中,服務器和服務器中的服務器存儲庫)並且工作正常。服務層重複我的存儲庫

但是,這是很常見的,我需要在服務的方法來獲得唯一對象在我的倉庫,像這樣(服務類):

public class ProductService { 

    private readonly IUnitOfWork _uow; 
    private readonly IProductRepository _productRepository; 

    public ProductService(IUnitOfWork unitOfWork, IProductRepository productRepository) { 
     this._uow = unitOfWork; 
     this._productRepository = productRepository; 
    } 

    /* this method should be exists in DDD ??? It's very common */ 
    public Domain.Product Get(long key) { 
     return _productRepository.Get(key); 
    } 

    /* other common method... is correct by DDD ? */ 
    public bool Delete(long key) { 
     usign (var tx = _uow.BeginTransaction()) { 
     try 
     { 
      _productRepository.Delete(key); 
      tx.Commit(); 
      return true; 
     } catch { 
      tx.RollBack(); 
      return false; 
     }   
     } 
    } 

    /* ... others methods ... */ 

} 

此代碼是正確的DDD?對於每個服務類,我有一個存儲庫,並且對於每個服務類需要我爲一個實體做一個「獲取」方法?

謝謝你們

乾杯

回答

1

這看起來是正確的,從我的角度來看。我真的不喜歡在我的asp.net MVC項目中重複使用服務和存儲庫方法名稱,所以我選擇了一個通用的存儲庫方法/模式。這意味着我真的只需要一個或兩個Get()方法在我的存儲庫中檢索我的對象。這對我來說是可能的,因爲我使用的是實體框架,而我只是讓我的存儲庫的get()方法返回一個IQueryable。然後,我就可以做到以下幾點:

Product product = from p in _productRepository.Get() where p.Id == Id select p; 

你或許可以使用LINQ複製此NHibernate的 - > NHibernate的。


編輯:這適用於DDD,因爲這仍然允許作爲數據庫我使用(NHibernate的,EF,等..),只要我交換我的DAL /倉庫支持IQueryable的。

我不知道如何做一個沒有IQueryable的通用存儲庫,但是您可能可以使用委託/ lambda函數來併入它。


EDIT2:以防萬一我沒有正確地回答你的問題,如果你是問你是否應該打電話給你的資料庫的get()從服務方法,然後是的,這是正確的DDD設計也是如此。原因是服務層應該處理所有的業務邏輯,所以它決定如何以及檢索什麼數據(例如,你想按字母順序,無序等等)。這也意味着它可以在刪除和/或保存前在需要時進行驗證或驗證。

這意味着服務層並不關心數據的存儲和檢索方式,它只決定存儲和檢索哪些數據。然後它會調用存儲庫以正確處理請求,並以服務層告訴它的方式檢索/存儲數據。因此你有正確的關注點分離。

9

您的ProductService看起來並不像遵循域驅動設計原則。如果我理解正確,它是介紹和域之間應用層的一部分。如果是這樣,ProductService上的方法應該對產品有商業意義。

讓我們來談談刪除產品。它是否像在數據庫上執行刪除操作一樣簡單(NHibernate,或其他?)我認爲它不是。那些引用即將被刪除的產品的訂單呢?等等等等。順便說一句,Udi Dahan在刪除實體上寫了一個great article。底線是,如果你的應用程序如此簡單以至於服務確實複製了你的存儲庫並且只包含CRUD操作,那麼你可能不應該做DDD,扔掉你的存儲庫並讓服務在實體上運行(這將是簡單的數據容器在這種情況下)。另一方面,如果存在複雜的行爲(例如處理「已刪除」產品的行爲),那麼在DDD路徑中有一點意義,我強烈建議這樣做。

PS。儘管採用了哪種方法(不管是否DDD),您最終還是會鼓勵您使用一些面向方面編程來處理事務和異常相關的問題。您最終將獲得許多方法,例如具有相同TX和異常處理代碼的DeleteProduct。