SignalR 在 DDD 架构中属于什么位置?

use*_*980 5 domain-driven-design signalr

我有一个 DDD 应用程序,我试图了解 SignalR 在我的层中的位置:

1. Presentation (Angular)
2. Distributed Services (Web API)
3. Application
4. Domain
5. Data
Run Code Online (Sandbox Code Playgroud)

基本上,当有新数据时,我的 SignalR 集线器会通知客户端(Angular Web 应用程序)。为此,我在后台线程中运行后台服务,该服务每隔一段时间检查数据库并在有新数据时通知客户端。

我倾向于这样思考:

  1. SignalR 集线器属于该Presentation层。鉴于我的演示项目纯粹是客户端(Angular),我将在 Presentation 下添加一个新项目,仅用于集线器。
  2. 每隔一段时间检查数据库的后台服务似乎适合该Application层。我会INotify用一个Notify方法注入一个接口,我会用 SignalR 来实现。

这是否符合 DDD 原则?

Chr*_*mon 5

DDD 就是确保对数据的更改仅以明确定义的方式发生,并且执行这些更改的代码是用通用语言的术语定义的,该语言在整个业务中(不仅仅是开发团队)都可以很好地理解)。

DDD 对用于与用户和其他系统交互的机制保持沉默,除了推荐分层架构 - 听起来您已经在这样做了。

所以 - 我不会在这里太担心 DDD - 但值得考虑您的整体架构方法 - 就分层架构模式而言,与您的方法非常匹配的一种称为端口和适配器洋葱架构。(见12

在此架构中,系统外部被视为一组适配器,可在特定技术和应用程序层之间进行适应。在您的情况下,您的 WebAPI 层是适配器的一个示例。

我建议创建一个新的 SignalR 适配器 - 您可以将其视为与 WebAPI 适配器相同的“级别”(尽管在端口和适配器用语中,它是一个“输出”适配器,因此您可以将其绘制在洋葱的右下角) 。

就后台进程的位置而言 - 就我个人而言,我不会认为它是应用程序层的一部分,因为它不指导应用程序中的任何用例或流程。因此,您可以将其放入 SignalR 适配器中,或者为其创建一个新的专用组件。

也就是说,您可能会发现 DDD 中的另一个有用的概念 - DomainEvents - 它们可以完全消除对后台线程的需要。在您的 SignalR 适配器中,包括注册以处理 DomainEvents 的事件处理程序,并在这些处理程序中,通过 SignalR 将有关事件的信息传播到客户端表示层 - 根本不需要轮询数据库!(警告 - 根据您的域事件实现,您可能需要在成功保留聚合之前考虑通过 SignalR 发布广告事件的风险……但这完全是另一个主题。)