我正在考慮改進我當前的存儲庫GetAll
方法實現,並在下面寫了一個代碼。我試圖在Google上找到這種方法的想法,但沒有成功。所以請查看代碼並幫助我回答以下幾個問題。這裏被簡化例如:存儲庫實現
class Service
{
public void DoOperation()
{
// Let's say we need to retrieve users by criteria
var items = UnitOfWork
.Over<User>() // Get repository of User
.GetAll() // Start querying
// If we need simple WHERE then use:
.Where(x => x.Email == "[email protected]")
// If we need more complex condition then use specification:
.Using(new UserNameContains("John"))
// Execute:
.List();
}
}
class UnitOfWork
{
public Repository<T> Over<T>()
{
// Get from DI container or injected field
return new Repository<T>();
}
}
class Repository<T>
{
public QueryWrapper<T> GetAll()
{
return new QueryWrapper<T>(Session.QueryOver<T>());
}
}
class QueryWrapper<T>
{
// Query from DB session. Init from constructor.
private IQueryOver<T> _query;
public QueryWrapper<T> Where(Expression<Func<T, bool>> expression)
{
_query = _query.Where(expression);
return this;
}
public QueryWrapper<T> Using(Specification<T> spec)
{
var spec = new TSpec();
_query = spec.Apply(_query);
return this;
}
public IEnumerable<T> List()
{
return return _query.List();
}
}
abstract class Specification<T>
{
public abstract IQueryOver<T> Apply(IQueryOver<T> query);
}
class UserNameContains : Specification<User>
{
// Init from constructor:
private string _name;
public override IQueryOver<User> Apply(IQueryOver<User> query)
{
return /* apply filter condition here */;
}
}
因此,作爲一個結果,我們得到這樣的好處:
- 不再需要創建自定義的回購。單一的通用就夠了。
- 自定義規範實現現在與數據層分離並且可測試。
- 易於使用的服務。
- 我們總是能夠延長
QueryWrapper
支持像OrderBy
等 - 額外的方法和它仍然是單元測試。
請您指點我的方法泄漏或提供您對問題的看法?此外,鏈接到現有的文章將是偉大的。