

















依赖过深会导致对象图复杂化,增加启动成本和内存消耗,同时增强隐式耦合,降低系统可测试性和可维护性。在高并发场景下还可能导致事务边界失控和生命周期错配风险。从架构角度来看,依赖过深说明模块边界划分不清晰,属于设计层面的复杂度失控问题。
但 IOC 只是基础设施,真正的架构能力体现在如何控制依赖深度、如何设计模块边界,以及如何防止依赖失控。
你可以回答:
因为生命周期不对称。Singleton 生命周期长于 Scoped,如果注入 Scoped,会导致依赖俘获,造成逻辑内存泄漏、已释放对象访问以及线程安全问题。正确做法是通过作用域工厂动态创建 Scope。
你可以这样答:
生命周期依赖必须满足包含关系,被引用对象的生命周期不能短于引用它的对象。否则会导致依赖俘获问题,引发内存滞留、已释放对象访问以及线程安全风险。
依赖生命周期问题,通常暴露两个更深层问题:
职责是否划分合理?
是否把数据库操作放到了不该是单例的服务中?
所以基础设施一次创建永久使用就用 singletion 其他都是scoped
为什么不考虑 transient 因为每次都需要创建对象 无法共享 在高并发系统中需避免频繁创建重对象,否则会增加 GC 压力。
|
生命周期 |
创建时机 |
存储位置 |
释放时机 |
典型场景 |
|
Singleton(单例) |
第一次解析时 |
Root Provider(根容器) |
应用关闭 |
缓存、客户端 |
|
Scoped(作用域) |
每个 Scope 第一次解析 |
当前 Scope |
Scope 结束 |
DbContext |
|
Transient(瞬时) |
每次解析 |
不缓存 |
由 GC 回收 |
轻量对象 |
1️⃣ 纯算法类 → Singleton
规则计算核心算法
凭证格式构建器
2️⃣ 业务编排类 → Scoped 全局唯一
例如:
销账应用服务
├── 调用规则引擎
├── 调用凭证生成器
├── 调用仓储
└── 发布事件
这个必须 Scoped。 作用域 一次请求
因为它涉及:
事务
用户上下文
数据库
3️⃣ 基础设施类 → Singleton
Redis 客户端
MQ 客户端
配置读取器
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。