首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体可以访问存储库吗?

问实体可以访问存储库吗?
EN

Stack Overflow用户
提问于 2009-05-06 01:39:59
回答 5查看 8.8K关注 0票数 32

我刚刚开始使用DDD,所以这可能是一个愚蠢的问题……

实体可以(通过一些IRepository接口)访问存储库以在运行时获取值吗?例如,我想对属性强制执行“默认”选择:

代码语言:javascript
复制
class Person {
    private Company _employer;

    public Company Employer {
        get { return _employer; }
        set { 
            if(value != null) {
                _employer = value;
            } else {
                _employer = employerRepository.GetDefaultEmployer();
            }
        }
    }

    ...
}

我的问题是,惠特做这样的事情是对DDD原则的可怕违反。如果不是,我的下一个问题是提供存储库的最佳方式是什么?是否应该在创建Person对象时提供它?

谢谢,P

EN

回答 5

Stack Overflow用户

发布于 2009-05-06 01:54:08

它不是一个可怕的DDD的违反它是一个可怕的违反...好吧..。这简直太可怕了(我开玩笑地说) :)。

首先,你的实体依赖于拥有一个存储库...这并不理想。理想情况下,您希望让存储库创建Person,然后为其分配在当前域上下文中有效所需的所有内容。

所以当你需要一个人的时候,你可以去personRepository.GetPersonWithDefaultEmployer()并返回一个填充了默认雇主的人。personRepository将依赖于一个employerRepository,并在返回它之前用它来填充person。

代码语言:javascript
复制
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;
    }
}
票数 26
EN

Stack Overflow用户

发布于 2011-03-22 17:58:23

你的问题的答案是标准的:,它取决于。

作为一条经验法则,永远不要这样做。保留你的实体而不引用存储库。

在一些极其罕见的情况下,如果你有一个非常、非常、非常好的理由这样做,请添加一个很大的注释来解释为什么要这样做:添加引用或使用Double Dispatch传递存储库的帽子

此外,如果您希望遵循DDD原则,强烈建议您具有领域专家和迭代开发过程(请参阅Eric Evans - what i've learned since the book )。

与您的领域专家一起,您应该定义绑定上下文,最重要的是定义聚合及其聚合根,以及它们的实体和值对象。在DDD道路上走下去一开始并不容易,但回报是值得的。

以下是关于您发布的代码的一些内容:

  1. 不建议在实体上使用公共setter。使用更好地表达意图的方法。
  2. 如果在未初始化_employer字段的情况下创建person实例,则Employer属性的getter将返回null。如果您随后将Employer属性的值设置为null,则下一次调用getter将返回一个非null值。
  3. 调用者设置人员的雇主(通过公共setter或公共方法)应该知道它想要设置的确切的Company实例,即使它是默认实例。也许调用者可以拥有对存储库的引用。
  4. 根据具体的域,公司可能是一个值对象。在这种情况下,您可以用值对象的默认值来初始化_employer,而不是用null初始化它。如果你只有很少的公司(1-2家),而且它们是不变的,没有特定的行为,情况可能就是这样。
票数 7
EN

Stack Overflow用户

发布于 2013-08-12 02:02:41

我认为说一个实体不应该知道存储库很容易,但很难将其付诸实践。特别是当一个聚合在它内部获得了一个很大的vo集合时,我们必须重构它,并将像add这样的操作委托给一些实际充当存储库的域服务,以避免将整个集合加载到内存中的开销。

但我认为让实体知道存储库是不合理的。如果有必要,使用域服务 instead.We还应该考虑存储库是否违反了Single Responsibility原则--它应该被认为是聚合根的集合,而不是普通的工厂。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/827670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档