1

我正在编写一个考虑到 DDD 的应用程序,并试图通过将域逻辑和行为委托给实体来避免出现贫血的域模型。在构建作为聚合根的实体并且需要创建需要由工厂类处理的子实体时,我遇到了一个问题。这是一个例子:

我有以下实体PageUrlLayout。使我的模型中的 Page 是PageaUrl和 a Layout- 没有这两个,Page对象将无效。在一个简单的模型中,Page构造方法将简单地将这两个对象创建为私有属性。但是,Url有一个特定的要求;它必须从页面的标题(或 slug)创建,并且必须是唯一的(通过附加“-1”、“-2”或类似的东西来确保)。这需要与存储库进行通信。

我最初的想法是将UrlFactory对象传递/注入到Page构造函数并Page创建Url它需要的对象,但我一直在阅读有关如何将服务注入实体是一个坏主意的信息。

所以,我的问题是;有没有一种方法——或一种既定的模式——允许实体在没有贫乏的域模型的情况下构建其复杂的子实体,或者在这种情况下注入工厂是一种有效的解决方案?

4

2 回答 2

2

If you consider URL construction as a technical concern, you could have an UrlFactory in the Infrastructure layer

in C# :

public class UrlFactory 
{
  public string CreateUrl(string title)
  {
    var url = // ... construct URL from the title here

    return _pageRepository.NextAvailableUrlLike(url);
  }
}

and then call it from your Application layer service.

If you see it as a Domain concern, Url construction logic could be in a Domain Service instead. The line calling the repository would be moved to the Application layer Service :

public void CreatePage(string title)
{
  var potentialUrl = _urlService.CreateUrl(title);
  var realUrl = _pageRepository.NextAvailableUrlLike(url)
  new Page(title, realUrl, ...); // do whatever you want with the new Page instance
}
于 2015-03-18T11:44:55.443 回答
0

不要将工厂类注入聚合,而是使用工厂方法。然后在聚合中创建方法“validate(Validator)”(聚合只知道它可以被验证,但它不会实现如何做的逻辑)。

将作为参数传递给您的验证方法的验证器类将需要一个方法 -> validateObject(this)。您将聚合实例传递给 validateObject,以便它可以访问您的属性。

验证器类可以注入存储库。当您运行 validateObject 方法时,它将在数据库中搜索唯一性。

于 2015-03-16T07:52:31.780 回答