You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#整洁架构中如何发起HTTP请求?DDD实践困惑求解

基于DDD/整洁架构的方案选择

首先直接排除选项C:直接在Blazor UI或API控制器中调用HttpClient并触发事件的做法完全违反了整洁架构的依赖原则和关注点分离。UI/API属于架构最外层,不应直接处理业务逻辑或外部服务调用,这会导致代码重复(Blazor和控制器要写两遍相同逻辑)、业务逻辑分散,后续维护和扩展成本极高。

接下来分析选项A和B:

选项B的问题

如果InstanceService是领域服务,那么它的职责应该是处理跨聚合根的领域逻辑,或者无法归属到单个聚合根的核心业务规则。直接在领域服务中发起HTTP请求是错误的——HTTP调用属于基础设施层的外部依赖,领域层作为内层,绝不应该依赖外层的基础设施组件,这会打破整洁架构的依赖方向,导致领域逻辑与外部实现耦合。

如果InstanceService是应用服务,虽然可以用来协调流程,但直接在其中发起请求仍然不如事件驱动的方式解耦,并非最优解。

推荐选项A(调整细节后)

选项A的核心思路是正确的,但需要明确各层职责边界,避免领域模型越权处理外部依赖:

  1. 领域层(Instance聚合根):

    • 在Instance中实现OperationA()方法,仅聚焦核心业务规则:比如检查当前Instance是否处于允许发起OperationA的状态(如未在执行其他操作、状态正常),然后更新自身状态(如标记为OperationAInProgress),最后触发领域事件OperationARequestInitiatedEvent(事件中携带Instance的标识等必要信息)。
    • 领域模型只负责自身的状态变更和领域规则,不涉及任何外部调用。
  2. 基础设施/应用层:

    • 实现事件处理器监听OperationARequestInitiatedEvent,在处理器中调用HttpClient发起/operationA请求(这部分属于基础设施层的外部服务实现)。
    • 请求完成(成功或失败)后,触发OperationAFinishedEvent(可以是应用事件或集成事件),由对应的处理器执行后续操作:
      • 通过仓储更新Instance的最终状态(如OperationASucceeded或OperationAFailed);
      • 执行其他业务流程(如通知相关方、更新关联数据等)。

这种方式的优势:

  • 符合整洁架构的依赖规则:领域层不依赖外层,外层依赖领域层;
  • 业务逻辑高度内聚在领域模型中,确保核心规则不分散;
  • 事件驱动的设计解耦了领域操作与外部调用,后续修改外部请求实现(如更换HttpClient、调整请求逻辑)不会影响领域层;
  • 无论是Blazor UI还是API控制器,只需调用应用层的用例(或直接触发领域操作),无需重复编写业务逻辑。

补充:如果你的OperationA需要跨多个聚合根协作,才需要引入领域服务,但从当前描述看,操作仅针对单个Instance,因此聚合根自身的方法足够。

内容的提问来源于stack exchange,提问作者Mathieu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 22:30:51