在做分层架构、尤其是 DDD(Domain-Driven Design) 时,团队最容易踩的一个坑,就是:
到底哪些扩展方法应该放 Shared?
Shared 层究竟是“工具箱”,还是“垃圾桶”?

别小看这个问题。Shared 层一旦放错东西,越到后期越会让你的系统耦合不断膨胀,最后变成“不敢动的巨大泥球”。

今天我们就彻底讲清楚:

  • Shared 层到底负责什么?

  • 哪些扩展方法可以放?

  • 哪些绝对不能放?

  • 如何让项目越写越清晰,而不是越写越乱?


🧩 一、Shared 层究竟是什么?

很多团队对 Shared 的理解非常模糊:
能共享的放 Shared,不知道放哪的也放 Shared……
久而久之,Shared 就变成了万能垃圾桶。

在 DDD 中,Shared 的真正含义是:

它是跨层复用的通用技术能力,而不是业务逻辑的归宿。

换句话说,Shared 应该是一个“无业务味道”的工具箱。

它可以包含:

  • ✔ 通用工具类(Utility)

  • ✔ 通用扩展方法(Extensions)

  • ✔ 跨层可复用的模型(例如:Result、PaginatedList)

  • ✔ 通用异常类型(AppException 等)

它不应该包含:

  • ❌ 任何业务领域相关的逻辑

  • ❌ 带业务语义的扩展方法

  • ❌ 依赖特定模块、特定上下文的代码

Shared 的定位必须非常纯粹。


🛠 二、基础工具扩展方法能不能放 Shared?

答案非常明确:
👉 能,而且应该放。

比如以下都是典型属于 Shared 的扩展方法:

  • StringExtensions.IsNullOrEmptySafe()

  • DateTimeExtensions.ToUnixTimeMilliseconds()

  • EnumerableExtensions.Batch<T>()

  • ObjectExtensions.DeepClone()

这些方法有共同点:

  1. 不涉及业务

  2. 用途广且跨层复用

  3. 不依赖任何领域对象

  4. 技术属性强于业务属性

也就是说,放到 Shared 完全符合 DDD 的边界规则。


🚫 三、哪些扩展方法绝对不能放 Shared?

以下扩展方法千万不能放 Shared:

❌ 示例 1:带业务含义的扩展方法

public static decimal CalculateTotal(this Order order)

❌ 示例 2:需要访问 Repository 或 Domain Service

public static bool IsVIP(this User user, IUserRepository repo)

❌ 示例 3:依赖业务规则(如计费、审批策略)

public static Price WithTax(this Money money)

这类扩展方法的特征是:

  • 依赖 Domain 模型

  • 依赖业务规则

  • 涉及领域行为

  • 在业务变化时需要调整

👉 这种逻辑必须属于 Domain,而不是 Shared。

一旦错误放入 Shared,就会让 Shared 强依赖 Domain、Application,甚至被反向依赖,
最后整个系统会变成彼此递归引用的混乱结构。


🎯 四、一句话判断法

为了让团队不再争论,给你一个永远适用的判断公式:

通用技术 → Shared
业务逻辑 → Domain

只要业务一变化就会受影响的代码,永远不能放 Shared。

而“放在哪都可以”的代码,通常就应该在 Shared。

这句话能帮你避免 80% 的架构分层问题。


🧱 五、推荐的项目结构(示例)

src
 ├─ Domain
 │   ├─ Entities
 │   ├─ ValueObjects
 │   └─ Services
 ├─ Application
 ├─ Infrastructure
 ├─ Shared
 │   ├─ Extensions
 │   ├─ Common
 │   └─ Results

你会发现 Shared 非常轻,Domain 非常干净,Application 和 Infrastructure 依赖清晰。

这才是 DDD 中成熟工程结构的模样。


🚀 六、总结

基础工具扩展方法放 Shared ——
✔ 完全符合 DDD
✔ 易于复用
✔ 边界清晰
✔ 避免耦合扩散

业务扩展方法放 Domain ——
✔ 聚合行为归位
✔ 模型更具有业务表达性
✔ 架构更可维护

Shared 不是垃圾桶,它是技术资产库。
Domain 不是工具包,它是业务智慧的核心。

让每段代码“放对位置”,系统就会越写越稳定。


最后

👋 如果你也在关注

青岛 / 烟台本地的软件构建、

数字化系统设计,或小程序相关话题,

欢迎在评论区交流你的想法。

让我们一起,把逻辑与体验,

变成真正可用的产品。

MUZINET · 技术记录与思考

山东有客赞信息技术有限公司

muzinet.webyt.com.cn

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐