2011-03-01 24 views
1

嗨我試圖在EF4上創建一個通用庫。我希望創建一個存儲庫類,以保持ObjectContext自身的狀態,而不是使用不同的Repository & UnitOfWork實現。我的界面如下所示:通用庫設計

/// <summary> 
/// Contract for base generic repository 
/// </summary> 
public interface IRepository 
{ 
    ActionResult SaveData<TEntity>(TEntity entityObj, bool commitTransaction) where TEntity : IEntity, new(); 

    ActionResult SaveData<TEntity>(ICollection<TEntity> entityObjects, bool commitTransaction) where TEntity : IEntity, new(); 

    ActionResult DeleteData<TEntity>(TEntity entityObj, bool commitTransaction) where TEntity : IEntity, new(); 

    ActionResult DeleteData<TEntity>(ICollection<TEntity> entityObjects, bool commitTransaction) where TEntity : IEntity, new(); 

    ICollection<TEntity> SelectAll<TEntity>() where TEntity : IEntity, new(); 
    ICollection<TEntity> SelectByCondition<TEntity>(Func<TEntity, bool> condition) where TEntity : IEntity, new(); 
} 

ActionResult是一個類,它告訴我特定的事務是否成功執行。現在我不想維護倉庫之外的事務狀態。所以每次保存/刪除我們都可以傳遞布爾值。第一次,事務對象可以在內部檢查,然後當我打電話給我的最後一個事務時,我可以發送committransaction true,這將調用SaveChanges()函數。

我的問題是:這種方法設計好嗎?我可以面對什麼問題?

回答

3

我看到這個實現有很多問題。

  • 明確告訴每個保存和刪除操作是否提交都很麻煩並且容易出錯。只是意外地將一個操作設置爲假,而您的休息原子。控制交易不應該在該級別完成。
  • SelectByCondition需要一個Func<T, bool>謂詞,這意味着必須在內存中加載和過濾完整的數據庫表。更好的設計是使用表達式樹。
  • 你說你定義了一個「存儲庫類,它將自己維持在ObjectContext的狀態」,但實際上你定義了一個工作單元:-),因爲存儲庫被用於單一類型的對象。
  • 每種方法都採用TEntity類型的參數,而這在接口級更適合,因爲那樣你就會遵循存儲庫設計模式。例如:IRepository<TEntity>。這樣的設計會使使用類型安全。

看一看this article。它描述了一個(相當抽象的)實現作品和存儲庫單元的方式,同時允許你對它們進行LINQ查詢並允許它們成爲單元可測試的。

1

您基本上已經創建了一個混合工作單元和存儲庫接口,從而打破了SRP。我建議你堅持通常通過IoC容器注入到倉庫的工作單元。你仍然可以使用通用的Repository。這是一個衆所周知的模式,特別是圍繞EF提供了大量的社區樣本(請參閱單元測試EF的鏈接)。

在可能的情況下使用常見模式而不是烘烤自己的模式,將會爲現在或將來的團隊提供更好的服務。

+0

+1。我完全同意。 – Steven 2011-03-01 19:04:27