近來發現很多ASP.NET MVC的例子中都使用了Repository模式,比如Oxite,ScottGu最近發佈的免費的ASP.NET MVC教程都使用了該模式。就簡單看了下。
在《企業架構模式》中,譯者將Repository翻譯爲資源庫。給出如下說明:
通過用來訪問領域對象的一個類似集合的接口,在領域與數據映射層之間進行協調。
在《領域驅動設計:軟件核心複雜性應對之道》中,譯者將Repository翻譯爲倉儲,給出如下說明:
一種用來封裝存儲,讀取和查找行爲的機制,它模擬了一個對象集合。
使用該模式的最大好處就是將領域模型從客戶代碼和數據映射層之間解耦出來。
我們來看下在LinqToSql中如何應用該模式。
1. 我們將對實體的公共操作部分,提取爲IRepository接口,比如常見的增加,刪除等方法。如下代碼:
interface IRepository<T> where T : class
{
IEnumerable<T> FindAll(Func<T, bool> exp);
void Add(T entity);
void Delete(T entity);
void Save();
}
2.下面我們實現一個泛型的類來具體實現上面的接口的方法。
public class Repository<T> : IRepository<T> where T : class
{
public DataContext context;
public Repository(DataContext context)
{
this.context = context;
}
public IEnumerable<T> FindAll(Func<T, bool> exp)
{
return context.GetTable<T>().Where(exp);
}
public void Add(T entity)
{
context.GetTable<T>().InsertOnSubmit(entity);
}
public void Delete(T entity)
{
context.GetTable<T>().DeleteOnSubmit(entity);
}
public void Save()
{
context.SubmitChanges();
}
}
3.上面我們實現是每個實體公共的操作,但是實際中每個實體都有符合自己業務的邏輯。我們單獨定義另外一個接口,例如:
interface IBookRepository : IRepository<Book>
{
IList<Book> GetAllByBookId(int id);
}
4.最後該實體的Repository類實現如下:
public class BookRepository : Repository<Book>, IBookRepository
{
public BookRepository(DataContext dc)
: base(dc)
{ }
public IList<Book> GetAllByBookId(int id)
{
var listbook = from c in context.GetTable<Book>()
where c.BookId == id
select c;
return listbook.ToList();
}
}
上面只是爲大家提供了一個最基本使用框架。