在学习域驱动设计时,我一直在整理以下解决方案(请注意,这种排序是词典式的,而不是依赖性的表示):
以下是每个项目的概要:
Domain.Models:域实体和值对象(例如
Order
)Domain.Interfaces:域服务接口和存储库接口(例如
IOrderService
,IOrderRepository
)Domain.Services:域服务接口的具体实现(例如
OrderService
)Infrastructure.Data:存储库接口的具体实现(例如
OrderRepository
)Infrastructure.DependencyResolution:依赖注入解析。
现在我想提供 非域 服务。一个例子是用于发送电子邮件的电子邮件网关。我为此创建了以下项目:
Infrastructure.Components:非域服务的具体实现
我将把这些非域服务的接口放在哪里(例如,IEmailGateway
)?
Domain.Services 项目需要访问它(OrderService
可能需要您发送通知),所以它会进入 Domain.Interfaces < / STRONG>?我会说不,因为发送电子邮件不是特定于域的活动。
答案 0 :(得分:1)
我会说不,因为发送电子邮件不是特定于域的 活性。
当然,但你可以通过使用更高的域抽象来逃避。域名不关心电子邮件,但通知将是一个完美的域名概念。它实际上似乎已经成为普适语言的一部分,因为你在你的问题中使用了这个术语。所以有点像INotifier
而不是IEmailGateway
。
替代方法可能是:
让总体Application Service通过基础架构中定义的IEmailService接口发送电子邮件。
让订单实体或域服务引发Domain Event。基础架构层中的EmailService会侦听它并发送电子邮件。
答案 1 :(得分:1)
如果发送电子邮件不是您的有限上下文的概念,那么它意味着它是另一个的一部分。因此,您应该应用一些有界上下文集成模式,例如域事件的反腐败层。
无论你选择什么,我都会看到你的结构和解决方案的另一个问题,这将消除问题中的问题。尝试根据有界上下文和使用泛在语言的模块而不是对象类型来构建应用程序。因此,您应该拥有产品,客户,货件等,而不是接口,型号和服务。