我正在将一些公共存储库基础结构合并到某些包装EF,L2SQL和WCF数据服务的应用程序中(尽管基础数据访问实现应该是任意的)。我已经对此事进行了一些阅读,但似乎无法找到真正满足的例子。通用存储库
我开始:
public interface IRepository : IDisposable
{
IQueryable<T> Query<T>();
void Attach(object entity);
void ForDeletion(object entity);
void SaveChanges();
}
但我喜欢用窄域合同(http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx)存储库的想法。以上内容让消费者知道存储库支持的所有实体类型。
我不会说这是不可能的,但我很难确信IQueryables本身不应该是存储库合同的一部分。我不是锅炉板代码的粉丝,我坚信你拥有的越多,引入的维护黑洞就越多。所以,我要说的是,这将是很难说服我,任何看起来像:
Public IEnumerable<Customer> GetCustomersWithFirstNameOf(string _Name) {
internalGenericRepository.FetchByQueryObject(new CustomerFirstNameOfQuery(_Name)); //could be hql or whatever
}
是什么,但一个完全糟糕想法。当你想要搜索名字和姓氏时怎么办?或者名字或姓氏等等。您最终将拥有一个拥有超过1000个操作的存储库,其中一半重复相同的逻辑。注:我不是调用代码应该是负责应用的所有过滤和这样的,而是具有互补的规范源对我来说很有意义:
public static class CustomerSpecifications
{
public IQueryable<Customer> WithActiveSubscriptions(this IQueryable<Customer> customers, DateTime? start, DateTime? end)
{
// expression manipulation
return customers;
}
}
// bind some data source
repository.GetQueryable().WithActiveSubscriptions();
好了,往前走,我认为有域模型明确仓库听起来像一个好主意,按以下格式:
public interface IRepository : IDisposable
{
void SaveChanges();
}
public interface IRepository<T>: IRepository
{
IQueryable<T> GetQueryable();
void Attach(T entity);
void ForDeletion(T entity);
}
然后
public class CustomerRepository:IRepository<Customer>
{
private ObjectContext _context;
// trivial implementation
}
,但我的这个问题是,它只是让我DELET e客户。那么我想删除客户地址的情况呢?也就是说,我使用存储库来查询客户实体,但是然后想要删除myCustomer.CustomerAddresses [0]?我需要创建第二个存储库来简单地附加和删除我想要的地址?
我想我可以有我的CustomerRepository是:
public class CustomerRepository:IRepository<Customer>, IRepository<CustomerAddress>
{
private ObjectContext _context;
// trivial implementation
}
这将让我重新使用存储库中删除CustomerAddresses,但我不知道我的感觉如何继承IRepository<T>
对于图形的每一个部分我想要公开删除...
public class CustomerRepository:IRepository<Customer>, IRepository<CustomerAddress> /* this list may get pretty long, and then I really just have a masked EF ObjectContext, don't I? */
{
任何人都有更好的实施建议吗?
因此,您对每个聚合根拥有GenericRepository ...因为在CustomerAddress中没有GenericRepository? –
Jeff
2010-11-29 00:52:29