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

在ASP.NET Core的Clean Architecture与Mediator模式下,Application层复杂可复用业务逻辑的放置位置咨询

在ASP.NET Core的Clean Architecture与Mediator模式下,Application层复杂可复用业务逻辑的放置位置咨询

嗨,Blake,你的困惑其实挺常见的——很多人从传统Service模式切换到CQRS+Mediator的Clean架构时,都会纠结业务逻辑的归属问题。先给你吃颗定心丸:你的思路完全没问题,在Application层创建Services文件夹存放ProductService这类封装复杂复用逻辑的服务是非常合理的做法!

下面给你拆解下具体的逻辑和可选方案:

  • 为什么适合放在Application层的Services里?
    Clean Architecture的核心是依赖方向:Domain层是最核心的业务规则层,Application层依赖Domain层,Infrastructure层依赖Application层。你的ProductService封装的是跨多个Command/Query的复用业务逻辑,它不属于单一的请求处理流程,也不属于Domain层中与实体强绑定的核心规则(比如Product.CalculateMemberDiscount()这种属于实体自身的行为,应该放在Domain层的实体类里)。把这类跨用例的复用逻辑放在Application层的Services中,既符合依赖规则,又能让你的Command/Query Handler保持简洁专注,只负责请求的协调和响应。

  • Service里该返回Domain实体还是DTO?
    你想得很对,这类Service应该返回Domain实体。因为Application层的核心职责是协调Domain逻辑与外部资源(比如Repository),而DTO是Presentation层和Application层之间的数据传输契约,属于更外层的交互概念。Handler拿到Domain实体后,再根据需要映射成DTO返回给Presentation层,这样能严格区分各层职责:Service专注业务逻辑实现,Handler专注CQRS的请求响应流转,DTO只在边界层做数据传输。

  • 有没有其他可选方案?
    当然,如果你觉得Services文件夹有点“回到老模式”的感觉,也可以根据逻辑类型选择其他方式:

    • Domain层的Domain Service:如果你的复用逻辑是涉及多个Domain实体的核心业务规则(比如OrderService.CalculateOrderTotal(Order, List<Product>)),那放在Domain层的Domain Service更合适——因为这属于业务核心规则,不依赖外部基础设施。但如果逻辑需要调用Repository或其他外部依赖,还是放在Application层的Service里更稳妥,毕竟Domain层不能依赖外部资源。
    • Application层的Helper/Utility类:如果只是纯计算类的复用逻辑(比如价格换算、日期校验),可以做成静态Helper类,但要注意这类类只做纯工具性计算,不能包含业务规则。

最后给你个实践小建议:不管用哪种方式,都要尽量让你的Command/Query Handler保持“薄”——Handler只负责接收请求、调用对应的Service/Domain逻辑、处理实体到DTO的映射、返回结果,不要在Handler里写复杂的业务逻辑,这样代码会更易维护、易测试。

备注:内容来源于stack exchange,提问作者Blake Rivell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 15:18:01