DDD - 具有多个"入口点的应用程序服务位置"

时间:2017-02-03 12:20:20

标签: c# domain-driven-design

DDD中的应用程序服务应该编排完整的业务用例,使用存储库来获取聚合,调用聚合上的方法以及管理数据库事务等基础架构问题。

在阅读Eric Evans,Vaughn Vernon和Scott Millett的书籍时,您可以找到关于如何分离项目的很好的例子。但我从未找到这种情况的明确答案。

假设您有一个域名和三个"入口点"与此域名进行通信:

  1. 用于同步操作的Rest API
  2. Messenger"守护进程" /"服务"在操作系统上运行以进行异步操作
  3. 用于维护操作的管理用户的Powershell cmdlet
  4. 如果每个入口点有一个DLL用于部署目的,那么您在哪里放置这些应用程序服务?

    选项A:所有入口点DLL引用的专用应用程序服务项目(DLL)。

    选项B:位于每个入口点的DLL中的应用程序服务。

    在第一个选项中,当多个入口点共享相同的用例时,您可以从代码重用中受益。单元测试也是如此。但是,理论上,您必须部署一个应用程序服务DLL,它具有针对某些入口点的过多功能。

    在第二个选项中,当它们共享相同的用例时,您必须在每个入口点的dll中复制代码(和测试),但理论上您可以控制基础架构关注,例如可能是数据库事务取决于执行是在API中的Powershell Cmdlet中。

    在我看来,真正的答案是个人偏好的问题。

    任何有这两种方法(成功或失败)经验的人都有一些提示或建议吗?

1 个答案:

答案 0 :(得分:2)

  

选项A:所有入口点DLL引用的专用应用程序服务项目(DLL)。

这大致是我期望看到的。这里有三个composition roots,它们应该始终共享相同的模型(以确保所有路径强制执行当前的业务不变量)和相同的记录簿(如果它们不共享相同的记录簿,它们真的根本不需要分享任何东西。

事实上,我强烈怀疑你可以将这些完全分开 - 在“微服务”中运行“模型”,并在上面部署三个接口,每个接口使用一个公共服务客户端DLL与该核心服务进行通信。 / p>

例如,您可以查看onion architecture。它与应用程序服务的单个dll的映像非常接近,每个组合都使用不同的接口来使自己的API适应模型。

  理论上,你必须为某些入口点部署一个具有太多功能的Application Service DLL。

就是这样;那里有一个交易。我的猜测是,在大多数部署中,运行单个胖DLL比尝试部署具有相同模型的不同子集的多个jar更具成本效益。

就我个人而言,我会从一个胖的微服务,一个设计良好的API和胖客户端开始,然后如果权衡支持选择。

  

只是为了确定我明白你的观点之一。您是否建议我的域(您称之为“模型”)应该公开API,而我的不同入口点(您称之为“组合根”)应该调用此API?

是的,这是对提案的公平描述,除了我想更清楚“应该公开API”部分。 API应该是明确的。也就是说,查看代码,您应该能够在代码中指向关注点分离的接缝

  • 部分是模特生活的地方
  • 那个部分是专业化的地方

您的选项B(如果您明确显示接缝)是在单个库中的这个想法。您的选项A就是这个想法,seam是两个库之间的接口(仍然在同一个进程中运行)。微服务就是这个想法,两个库在不同的进程中运行。

你得到不同的权衡 - 例如,如果模型在专用的微服务中运行,那么(a)改变模型是“容易的”,因为只有一个权限可以换出,并且(b)你现在拥有自由在任何可以与您的域服务交换消息的技术中实现您的专用接口,(c)您也可以独立于扩展专业化的方式扩展模型。

但是,您还会获得额外的复杂性,因为当客户端和服务器具有独立的部署周期时,您需要更多地考虑API的稳定性。