Architecture DDD特定领域/通用基础设施

Architecture DDD特定领域/通用基础设施,architecture,dependency-injection,domain-driven-design,Architecture,Dependency Injection,Domain Driven Design,关于域基础设施,可以将其视为: 常规:如何发送电子邮件/读取配置文件等 具体:如何向新用户(域实体)发送激活码 如果我想到依赖性: 域通用基础架构(用于日志记录、通用异常等) 特定基础架构通用基础架构和域(获取与基础架构相关的操作界面,如IActivationCodeSender,并能够实现EmailActivationCodeSender和SmsActivationCodeSender) 在这种情况下,我的应用层将负责向我的域实体传递(DI解析)所需的激活方法,比如: User.Reg

关于域基础设施,可以将其视为:

  • 常规:如何发送电子邮件/读取配置文件等
  • 具体:如何向新用户(域实体)发送激活码
如果我想到依赖性:

  • 通用基础架构(用于日志记录、通用异常等)

  • 特定基础架构通用基础架构和域(获取与基础架构相关的操作界面,如IActivationCodeSender,并能够实现EmailActivationCodeSender和SmsActivationCodeSender)

在这种情况下,我的应用层将负责向我的域实体传递(DI解析)所需的激活方法,比如:

User.Register(IActivationCodeSender activationCodeSender)
{
   // Register user and generate activation code 1234
   ...
   activationCodeSender.Send(this, "1234");
}
这不好吗?我是否应该改为在我的(通用)基础架构上工作,以确保它支持以统一的方式发送sms/电子邮件(我担心这种情况可能会给我的通用基础架构带来复杂性),并删除这个特定的基础架构,因为这样的层会将业务逻辑与基础架构相关的操作混合在一起?因此,我将使用以下方法:

INotificationSender的两个(通用)实现;电子邮件通知发件人和短信通知发件人


我建议用户注册后创建订阅。并将代码生成、通知逻辑放入订阅聚合器中。它将控制需要发送的内容和顺序。如果失败了怎么办,等等。您的通知可能是基础设施的一部分,因为它对您的域一无所知。只需收到电子邮件并发送出去

没有域基础结构。

你的客户不关心你将如何发送电子邮件。

< P>我建议你考虑使用具有这些基本原则的(维基百科):

  • 高级模块不应依赖于低级模块。二者都 应该依赖于抽象
  • 抽象不应该依赖于 关于细节。细节应该取决于抽象
  • 因此,我将把所有像
    IActivationSender
    这样的接口放在您的域中,然后在一个单独的基础设施项目中实现这个接口。正如您所提到的,使用DI在应用程序服务(或域服务)中注入所需的实现

    通过这种方式,您可以避免使用将接口的实现直接传递给
    域实体的位置:

    用户注册(INotificationSender activationcodender)

    取而代之的是:

    UserService.Register(用户)

    其中UserService可以是具有正确INotificationSender的域服务


    解决此问题的另一种完全不同的方法是使用域事件(请参阅)。按照此模式,您的用户实体将引发一个“UserCreated”事件,INotificationSender将依次订阅该事件。通过这种方式,您可以将发送通知消息与用户实体分离。

    因此您认为基础设施项目不应该引用域项目,而应该独立于任何域(没有域基础设施)工作?Arnis关于没有域基础设施的说法是正确的。任何基础设施接口都应该移动到应用程序级别并向上移动,在那里您可以拥有应用程序服务或DomainEventHandler,而DomainEventHandler又可以通过其构造函数要求INotificationSender。域应该100%不了解基础设施,甚至不了解基础设施接口。
    User.Register(INotificationSender activationCodeSender)
    {
       // Register user and generate activation code 1234
       ...
      // this.NotificationAddressInfo includes email address and mobile phone #
    
       activationCodeSender.Send(new Notification(this.NotificationAddressInfo, "Your activation code is 1234"));
    }