我刚刚开始使用DDD,所以这可能是一个愚蠢的问题……
实体可以(通过一些IRepository接口)访问存储库以在运行时获取值吗?例如,我想对属性强制执行“默认”选择:
class Person {
private Company _employer;
public Company Employer {
get { return _employer; }
set {
if(value != null) {
_employer = value;
} else {
_employer = employerRepository.GetDefaultEmployer();
}
}
}
...
}我的问题是,惠特做这样的事情是对DDD原则的可怕违反。如果不是,我的下一个问题是提供存储库的最佳方式是什么?是否应该在创建Person对象时提供它?
谢谢,P
发布于 2009-05-06 01:54:08
它不是一个可怕的DDD的违反它是一个可怕的违反...好吧..。这简直太可怕了(我开玩笑地说) :)。
首先,你的实体依赖于拥有一个存储库...这并不理想。理想情况下,您希望让存储库创建Person,然后为其分配在当前域上下文中有效所需的所有内容。
所以当你需要一个人的时候,你可以去personRepository.GetPersonWithDefaultEmployer()并返回一个填充了默认雇主的人。personRepository将依赖于一个employerRepository,并在返回它之前用它来填充person。
PersonReposotory : IPersonRepository
{
private readonly IEmployerRepository employerRepository;
//use constructor injection to populate the EmployerRepository
public PersonRepository(IEmployerRepository employerRepository)
{
this.employerRepository = employerRepository;
}
public person GetPersonWithDefaultEmployer(int personId)
{
Person person = GetPerson(personId);
person.Employer = employerRepository.GetDefaultEmployer(personId);
return person;
}
}发布于 2011-03-22 17:58:23
你的问题的答案是标准的:,它取决于。
作为一条经验法则,永远不要这样做。保留你的实体而不引用存储库。
在一些极其罕见的情况下,如果你有一个非常、非常、非常好的理由这样做,请添加一个很大的注释来解释为什么要这样做:添加引用或使用Double Dispatch传递存储库的帽子
此外,如果您希望遵循DDD原则,强烈建议您具有领域专家和迭代开发过程(请参阅Eric Evans - what i've learned since the book )。
与您的领域专家一起,您应该定义绑定上下文,最重要的是定义聚合及其聚合根,以及它们的实体和值对象。在DDD道路上走下去一开始并不容易,但回报是值得的。
以下是关于您发布的代码的一些内容:
发布于 2013-08-12 02:02:41
我认为说一个实体不应该知道存储库很容易,但很难将其付诸实践。特别是当一个聚合在它内部获得了一个很大的vo集合时,我们必须重构它,并将像add这样的操作委托给一些实际充当存储库的域服务,以避免将整个集合加载到内存中的开销。
但我认为让实体知道存储库是不合理的。如果有必要,使用域服务 instead.We还应该考虑存储库是否违反了Single Responsibility原则--它应该被认为是聚合根的集合,而不是普通的工厂。
https://stackoverflow.com/questions/827670
复制相似问题