我在我的ASP.NET MVC程序中使用了類似的方法,到目前爲止它工作得很好。
我IUnitOfWork
界面看起來是這樣的:
public interface IUnitOfWork
{
IRepository<TEntity> GetRepositoryFor<TEntity>() where TEntity : class;
void SaveChanges();
}
和相關IRepository
界面看起來是這樣的:
public interface IRepository<TEntity> : IQueryable<TEntity> where TEntity : class
{
TEntity Find(params object[] keyValues);
void Insert(TEntity entity);
void Update(TEntity entity);
void Delete(TEntity entity);
}
然後把它傳給我的服務,像這樣:
public abstract class BaseService
{
public BaseService(IUnitOfWork unitOfWork)
{
// etc...
}
}
你說得對,這很容易該服務可以解決它的存儲庫,而無需單獨將它們傳遞給構造函數,這在您可能在單個服務中使用多個存儲庫時很有用(例如,採購訂單和產品)。
使用ORM不可知界面的好處之一就是它可以輕鬆切換ORM。老實說,我從Entity Framework轉換到另一個ORM的機會很渺茫,但事實是,如果需要出現,我可以做到。作爲獎勵,我的服務更容易測試,而且我也發現這使得我的服務類更清潔,因爲它現在完全不知道正在使用的ORM,並且完全針對上面的兩個界面。
關於關於通用存儲庫接口的評論,我的建議是要務實,併爲您和您的應用程序做最適合的工作。在這個主題上有很多關於Stackoverflow的問題,並且他們的答案大致不同,關於哪個是最好的路線(例如,暴露IQueryable
vs IEnumerable
,泛型vs非泛型)。
我不有一個通用的存儲庫作爲玩弄你可能已經注意到,我的IRepository
界面看起來像IDbSet
;我採用這種方法的原因是它允許我的實現處理所有使用DbContext
E.G.實現的實體框架實體狀態管理。
public void Delete(TEntity entity)
{
if (Context.Entry(entity).State == EntityState.Detached)
{
EntitySet.Attach(entity);
}
EntitySet.Remove(entity);
}
如果我用IDbSet
我需要我的服務層,那麼這將需要對DbContext
依賴這似乎更加抽象漏水比我通用倉庫執行此。
如果您使用的是OR/M,那麼通用存儲庫並不真正起任何作用。 – jgauffin 2013-02-12 09:39:15
@jgauffin - 你願意爲我詳細闡述一下嗎? – Sam 2013-02-14 18:44:19
除非您爲每種實體類型定製它們,否則通用存儲庫不會直接使用OR/M提供任何好處。 – jgauffin 2013-02-14 19:29:18