【问题标题】:How to force the use of a domain service?如何强制使用域服务?
【发布时间】:2018-07-20 16:13:43
【问题描述】:

在您关于域服务的在线文档(“https://aspnetboilerplate.com/Pages/Documents/Domain-Services”)中,您有一个名为“我们如何强制使用域服务?”的部分。

在那里,您暗示有很多外部文档围绕将一种“策略”服务注入实体的概念作为执行此操作的一种方式,但是关于该类的实现的文章有点模糊,以及应该注入的位置和使用方式。我一直在互联网上搜索这种设计以强制使用域服务的示例,但没有找到任何东西。

只是浏览该文档会留下太多问题..

此外,我希望我能找到一个简单的 Abp 实现,它提供了一个示例,但找不到任何东西。

我对此非常好奇,因为我发现这是过去大型项目的一个大问题:开发人员在应用程序服务层编写自己的代码,而不知道在某些领域驱动中已经提供了这些功能“经理”服务。

您能否提供一个完整实施的概念的快速小样本?使用 Abp 会很好,但一个通用的例子也很好。

保重,

杰森

【问题讨论】:

  • 你可以把AssignToPersoninternal设置成只能被域服务调用。
  • 您总是可以使用方法注入,即order.CalculateTax(taxServiceProvider),其中ITaxServiceProvider 可能有一个名为GetTaxCalculatorFor(Country country, State state, TaxCode taxCode) 或类似的方法。因此,为了计算税款,您必须使用 TaxProvider 的一个实例,该实例可以解析特定国家/地区的税款计算服务。由于它全部封装在聚合根中,因此必须将服务传递给方法(您必须通过封装确保不能从聚合外部设置税值)
  • 更具体的例子见this post
  • 感谢曾。我考虑得越多,我就越不想要求实体了解外部服务。我愿意做一些简单而通用的事情,比如允许设置属性的策略,但基本上我不喜欢将依赖项注入我的实体的想法。目前正在权衡仅使用“内部”的利弊。
  • 好吧,你的聚合(不是实体!!!)会有这些外部依赖,但它是真正封装特定逻辑的唯一方法。否则,您将无法在订单中添加仓位并确保其保持一致状态。如果在上述情况下,您在外部进行计算,则可能会出现状态不一致的风险(即通过将错误的参数传递给计算它的方法)。

标签: domain-driven-design aspnetboilerplate


【解决方案1】:

一些想法:

  • 该代码中的策略模式在强制使用域服务方面没有任何作用。它只会使任务分配更加模块化,更加符合 SRP。

  • 防御性编程能为您做的只有这么多。当然,将AssignedPersonId 设置为protected 使其不能直接赋值是一件好事,但程序员也可以将其改回public。不要过分依赖技术代码来防止不良的开发人员行为 - 共享实践和团队文化会更有效率。

  • 质疑应用程序示例或模板代码(如您所做的那样)是合理的。不要把那个代码当作福音真理——它从一开始就不是为了示范。尝试自己的东西并从错误中吸取教训。经验不是可以通过这样的文件传递的。

【讨论】:

  • 我同意并感谢您的回复。我喜欢将类似“策略”的对象传递到只有域类可以访问的实体中的想法。我认为这是一个不错的技巧,如果它是某种我从未偶然发现的设计原则,我想阅读更多关于它的内容,或者看看它的实现。我在任何地方都找不到我为什么要问的任何东西。
  • 仔细想想,我猜这个政策更像是Specification pattern——虽然“政策”可能更适合那个特定的领域。
  • 实际上在 Abp 项目中,它们在与实体对象本身相同的程序集中实现域类,因此在属性上使用 internal 似乎是最简单的解决方案。不知道为什么昨晚深夜没有打到我 :-) 好奇是否对此有任何意见?像往常一样,我在这场辩论中看到了相互矛盾的意见。
猜你喜欢
  • 2017-02-06
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 2011-11-07
  • 2022-01-19
  • 2015-05-01
  • 2018-09-12
相关资源
最近更新 更多