我有一个问题。我们正在使用通用存储库,我们的域模型也是持久性模型,但这导致我们调整我们的域模型以与ORM对齐,例如: - 我们必须放置默认的私有构造函数和其他一些脏的更改,我们正在使用(本例中为Entity Framework),现在我们决定使用与我们的富域模型不同的持久性模型,但在这种情况下我们不能使用Generic Repository。 注意: - 我们使用工厂来创建我们的域模型,但我们使用AutoMapper将域模型转换为持久模型。
答案 0 :(得分:5)
这是一个棘手的问题,因为你正试图调和两种对立的DDD持久性方法,这些方法是由相反的思想流派设计的。
Generic Repository模式被一些人视为antipattern,可以追溯到早期DDD的采用,当时人们正在寻找简化DDD系统持久性的工具和技术。大多数实现最终在通用存储库的合同中暴露了ORM查询细节(在实体框架的情况下为IQueryable
),因为它们是您可以询问回购的各种事物之间的便利共同点。
最近的持久性模型方法是朝着相反方向迈出的一步 - 远离ORM。你所做的是引入一个额外的间接层,正是为了让你的域模型(也包括Repository接口)不受持久层特定内容的影响。
如果你仍然绝对肯定Generic Repository是通过代码重用获得的最佳权衡(我建议首先挑战),Greg Young gives us是一个合理的中间立场:
所以这里的答案是仍然使用通用存储库但要使用 组合而不是继承,而不是将其暴露给域 合同。
您可以利用相同的方法并利用该接缝将域模型/持久性模型映射投射到混合中。
这些方面的某些内容可能(未经测试):
public class FooRepository
{
private PersistenceRepository<FooPersistence> _innerRepository;
public Foo GetFooById(int id)
{
return MapToDomain(_innerRepository.GetById(id));
}
public void Add(Foo foo)
{
_innerRepository.Add(MapToPersistence(foo));
}
public IEnumerable<Foo> GetByCity(string city)
{
return _innerRepository.Find(f => f.City == city).Select(MapToDomain);
}
private Foo MapToDomain(FooPersistence persistenceModel)
{
// Mapping stuff here
}
private FooPersistence MapToPersistence(Foo foo)
{
// Mapping stuff here
}
}
public class PersistenceRepository<T> where T : PersistenceModel
{
public T GetById(int id)
{
//...
}
public void Add(T t)
{
//...
}
public IQueryable<T> Find(Func<T, bool> predicate)
{
//...
}
}
public abstract class PersistenceModel
{
}
public class FooPersistence : PersistenceModel
{
public string City { get; set; }
}