2011-01-21 86 views
5

我正在研究一個小型的ASP.NET MVC項目。
我想實現Nhibernate堅持MS Sql Server數據庫。 花了很長時間學習DDD和在互聯網上找到的其他項目,我決定去存儲庫模式。 現在我馬上面臨困境。
使用Nhinbernate時,我真的需要存儲庫嗎?
那豈不是更好有與Nhinbernate避免多次寫入類似的東西進行交互的服務層(我沒有在時刻一個服務層):ASP.NET MVC,Nhibernate和中小型項目庫

public Domain.Reminder GetById(Guid Code) 
{ 
    return (_session.Get<Domain.Reminder>(Code)); 
} 

public Domain.Reminder LoadById(Guid Code) 
{ 
    return (_session.Load<Domain.Reminder>(Code)); 
} 

public bool Save(Domain.Reminder Reminder) 
{ 
    _session.SaveOrUpdate(Reminder); 
    return (true); 
} 

public bool Delete(Domain.Reminder Reminder) 
{ 
    _session.Delete(Reminder); 
    return (true); 
} 

我發現一隻老Ayende的POST是針對倉庫的。
我知道圍繞這些話題有一個巨大的爭論,答案總是......依賴,但在我看來,如果抽象層數太多,事情會變得更加複雜和難以遵循。
我錯了嗎?

+0

只是一個小紙條。沒有中小型項目,現在它可能很小,但是明天你的經理會問你另一個特徵,然後是另一個特徵,最後你會有一個巨大的項目,具有中小型架構。我真的不喜歡Big Design Up Front,但有時你需要考慮一下。 – goenning 2011-01-21 14:00:06

+0

我完全同意你的意見,但是,實際上,如果不是因爲我未來可能不會使用nihbernate,我無法看到使用存儲庫的好處。它產生了許多額外的工作,我目前無法證明這一點。 – LeftyX 2011-01-21 14:52:17

回答

7

Ayende反對按照您的方式編寫知識庫,因爲您提出這個問題的原因是重複性代碼,NH可以處理所有問題。他主張只是直接調用NH,就像你將一個倉庫一樣,不要擔心。

我非常同意他的看法。除了更多的工作外,沒有什麼可以獲得的。

+0

我必須承認,這是我想聽到的答案:-) – LeftyX 2011-01-21 14:55:56

0

我發現你應該使用Repository/DAO/Whatever的一些原因。

  1. 單元測試。我從來沒有試圖模擬/存儲一個ISession,但我會說它應該比嘲笑或存儲Repository/DAO接口更復雜。
  2. 重複使用代碼。如果您將查詢直接寫入您的服務/控制器,那麼當您需要重新使用特定查詢時,您將最終複製該查詢。如果你把它封裝到一個Repository中,就調用它的方法。
  3. Single Responsibility Principle。將你的查詢擴展到你的控制器使你打破這個原則。
  4. NHibernate依賴關係。好的,這很難發生,但是如果你需要改變你的ORM,那麼這個版本庫會使它更容易(看起來,這很容易,不容易:))。或者甚至當您需要將用戶數據源從數據庫更改爲Microsoft Active Directory時,它會更容易。

這就是知道,不記得任何東西。

+0

謝謝奧寧。我不想在我的控制器中編寫查詢,而是在服務層中編寫查詢。我認爲這是放置一些業務邏輯的好地方。它不會在UI中,如果我想將我的服務層插入其他地方,它將是可重用的。 Nhibernate依賴。那麼,是的,我可以同意,但我認爲這不會很快發生,我認爲這與更改存儲庫不同。不管怎麼說,還是要謝謝你。 – LeftyX 2011-01-21 14:47:16

4

改爲使用通用存儲庫。每個類的一個存儲庫很容易被過度殺傷。

我使用Get,Load,Save方法和各種匹配方法(一個用於Linq,一個用於我的域查詢)使用一個存儲庫。

最後一種方法接受ICreateCritiera實現。以下是界面和它的一個實現。

public interface ICreateCriteria<T> : ICreateCriteria 
{ 
    DetachedCriteria GetCriteria(); 
} 

public class ChallengesAvailableToRound : ICreateCriteria<Challenge> 
{ 
    private readonly Guid _roundId; 

    public ChallengesAvailableToRound(Round round) 
    { 
     _roundId = round.Id; 
    } 

    public DetachedCriteria GetCriteria() 
    { 
     var criteria = DetachedCriteria.For<Challenge>(). 
      CreateAlias("Event", "e"). 
      CreateAlias("e.Rounds", "rounds"). 
      Add(Restrictions.Eq("rounds.Id", _roundId)); 

     return criteria; 
    } 
} 

這讓我可以將查詢分解到他們自己的類中,並輕鬆地在整個項目中重用它們。