在域驱动的体系结构中包含业务逻辑的位置

时间:2010-06-10 21:46:38

标签: architecture domain-driven-design webforms

我正在尝试学习有效的DDD练习,但我有一个基本的问题,我希望得到一些清晰的说明。

我正在使用ASP.NET WebForms,我正在创建一个用户下订单的情况。在提交订单时,代码隐藏检索用户,从表单上的输入构建订单,调用User.PlaceOrder()方法执行将订单对象添加到用户的订单集合,并调用存储库以保存记录到数据库。这是相当简单明了的。

现在我需要添加逻辑来发送订单确认电子邮件,我不确定放置此代码的适当位置或在何处调用它。在过去的日子里,我只是简单地将代码放在代码隐藏中并在构建顺序的同时调用它,但我想更接近实体的正确架构,所以我想获得一些信息。

感谢您的帮助!

3 个答案:

答案 0 :(得分:4)

对我来说,我尽可能地保持一切尽可能接近实体。过了一会儿,你会开始发现某些地方的东西比其他地方更合适。例如,可以仅基于实体的给定实例确定的业务逻辑应该在实体中。如果它需要更多的域知识,那么它可能属于域服务。

我把我的逻辑划分为三个方面,大部分都是:

  • 实体逻辑
  • 域名服务逻辑
  • 应用服务逻辑

例如,应用程序逻辑是我注册域事件的地方。个人而言,我认为电子邮件不属于域名。这是一项要求,而不是一种逻辑。如果我在那时有一个监听器,域可能会引发OrderSubmitted()事件,并且监听器有责任对其进行操作。该事件属于域,因为它描述了域上下文中的重要事件。然而,在我看来,应用程序对此的反应是不同的。

如Syznmon所述,Udi's blog是一个很好的资源。不过,我强烈建议Evan's book,以及他与lessons learned的演示文稿。

答案 1 :(得分:0)

我所做的是为所有逻辑引入一个逻辑层,代码隐藏仅用于处理请求,而存储库仅用于crud操作,这样你就可以完全将逻辑从应用程序的其余部分中分离出来并且很容易测试

答案 2 :(得分:0)

最好在将蜜蜂保存到数据库后将异步发送确认电子邮件。我会介绍一些消息总线(如NServiceBus)来处理这种情况。在与保存订单相同的事务中,您在总线上发布消息“订单已创建”。这些是订阅此消息并向客户发送电子邮件的处理程序。

为何异步?因为SMTP服务器有失败的倾向,并且发送电子邮件可能是相当漫长的任务,并且在如此长的时间内阻塞数据库表会引入死锁。我鼓励您查看Udi Dahan's blog:他是NServiceBus的作者,并且博客上有很多与您的确认电子邮件类似的案例。