DDD 领域特定/通用基础设施
关于域基础设施,可以将它们视为:
- 一般:如何发送电子邮件/读取配置文件等。
- 具体:如何向新用户(域实体)发送激活代码
如果我想到依赖项:
域名 <参考文献>> 一般基础设施(用于日志记录、一般异常等。)
特定基础设施
特定基础设施 参考文献>> 一般基础设施和域(获取与基础设施相关的操作接口,例如IActivationCodeSender,并能够实现EmailActivationCodeSender和SmsActivationCodeSender)
我的应用程序层在这种情况下,将负责将所需的激活方法传递(DI 解析)到我的域实体,让我们说:
User.Register(IActivationCodeSender activationCodeSender)
{
// Register user and generate activation code 1234
...
activationCodeSender.Send(this, "1234");
}
这不好吗?我是否应该在我的(通用)基础设施上进行工作,以确保它支持以统一的方式发送短信/电子邮件(我担心这种情况可能会给我的通用基础设施带来复杂性)并删除此特定基础设施从某种意义上说,该层会将业务逻辑与基础设施相关操作混合在一起?所以我会使用以下内容:
INotificationSender 的两个(常规)实现; EmailNotificationSender 和 SmsNotificationSender
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"));
}
Regarding domain infrastructure is it OK to think of them as:
- General: How to send an email / Read configuration file, etc..
- Specific: How to send an activation code to a new user (domain entity)
Where if i think of dependencies:
Domain < References > General Infrastructure (for Logging, General Exceptions, etc..)
Specific Infrastructure < References > General Infrastructure & Domain (to get infrastructure related operation interfaces like IActivationCodeSender and be able to implement an EmailActivationCodeSender & an SmsActivationCodeSender)
My application layer in that case will be responsible to pass (DI resolved) the desired activation method to my domain entity, let us say:
User.Register(IActivationCodeSender activationCodeSender)
{
// Register user and generate activation code 1234
...
activationCodeSender.Send(this, "1234");
}
Is this bad? should i instead work on my (General) Infrastructure to make sure it supports sending sms / email in a unified manner (I'm afraid such cases might introduce complexity to my General Infrastructure) and remove this Specific Infrastructure in the sense that such layer would mix the business logic with Infrastructure related operations? so instead i would use the following:
Two (General) implementations for the INotificationSender; an EmailNotificationSender and an SmsNotificationSender
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"));
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我建议您考虑使用具有以下基本原则的依赖倒置原则(来自维基百科):
因此,我会将诸如
IActivationSender
之类的所有接口放入您的域中,然后在单独的基础设施项目中实现此接口。正如您所提到的,使用 DI 在您的应用程序服务(或域服务)中注入所需的实现。这样您就可以避免使用双重调度模式,在这种模式中,您可以将接口的实现直接传递给
域实体
:而是使用类似以下内容的内容:
UserService.Register(user);
其中 UserService 可以是注入了正确的 INotificationSender 的域服务。
解决该问题的另一种方法可能是使用域事件(请参阅 乌迪·达汉斯的文章)。按照此模式,您的 User 实体将引发 INotificationSender 依次订阅的“UserCreated”事件。通过这种方式,您可以将发送通知消息与用户实体的关注点分离。
I would suggest you consider using the Dependency inversion principle that has these basic principles (from Wikipedia):
So I would put all the interfaces like
IActivationSender
in your domain, and then implement this interface in a separate infrastructure project. As you mention, use DI to inject the desired implementation in your application service (or in a domain service).This way you can avoid using the Douple dispatch pattern where you pass the implementation of the interface directly to a
domain entity
:And instead have something like:
UserService.Register(user);
Where UserService could be a domain service with the correct INotificationSender injected.
A completely other way of solving the issue could be to use Domain events (see Udi Dahans article). Following this pattern, your User entity would raise a "UserCreated" event that the INotificationSender would in turn subscribe to. This way you decouple the concern of sending notification messages from the User entity.
我建议用户注册后创建订阅。并将您的代码生成、通知逻辑放入订阅聚合器中。它将控制需要发送的内容以及顺序。如果失败该怎么办等等。您的通知可以是基础设施的一部分,因为它对您的域一无所知。只需收到电子邮件并发送出去即可。
I would suggest to create a subscription once user registered. And put your code generation, notification logic in the subscription aggregator. It will control what need to be sent and what is the sequence. what to do if fail, etc. And your notification can be very part of Infrastructure since it can know nothing about your domain. Just get email and send out.
没有域基础设施。
您的客户并不关心您将如何发送电子邮件。
There is no domain infrastructure.
Your customer does not care about how you are going to send e-mails.