我正在编写一个关注DDD的应用程序,并试图通过将doman逻辑和行为委托给实体来避免出现贫血领域模型。我遇到了一个问题,我遇到的是构建聚合根的实体,需要创建需要工厂类处理的子实体。这是一个例子:
我有以下实体:Page
,Url
和Layout
。是什么让我的模型中的页面为Page
,Url
和Layout
- 如果没有这两个,Page
对象将无效。在一个简单的模型中,Page
构造函数方法只是将这两个对象创建为私有属性。但是,Url
有特定要求;它必须是从页面标题 - 或者一个slug - 创建的,它必须是唯一的(通过附加" -1"," -2"或者其他东西来确保它类似)。这需要与存储库进行通信。
我最初的想法是将UrlFactory
对象传递/注入Page
构造函数并让Page
创建它需要的Url
,但我一直在阅读如何向实体注入服务是一个坏主意。
所以,我的问题是;有没有一种方法 - 或者一种已建立的模式 - 允许实体构建其复杂的子实体而不需要贫血域模型,或者在这种情况下注入工厂是一种有效的解决方案?
答案 0 :(得分:2)
如果您将网址构建视为技术问题,那么您可以在基础架构层中使用UrlFactory
在C#中:
public class UrlFactory
{
public string CreateUrl(string title)
{
var url = // ... construct URL from the title here
return _pageRepository.NextAvailableUrlLike(url);
}
}
然后从您的应用层服务中调用它。
如果您将其视为域关注点,则Url构造逻辑可能位于域服务中。调用存储库的行将被移动到Application层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
}
答案 1 :(得分:0)
不要将工厂类注入聚合,而是使用工厂方法。然后创建方法"验证(Validator)"汇总(聚合只会知道它可以被保留,但它不会实现逻辑如何去做)。
将作为参数传递给validate方法的Validator类需要有一个方法 - > validateObject(this)。 您将聚合实例传递给validateObject,以便它可以访问您的属性。
Validator类可以注入存储库。运行validateObject方法时,它将搜索数据库以进行统一。