某个服务注册为 Singleton 后,测试似乎更快,生产却出现共享状态或已释放对象错误。生命周期选择首先取决于状态和依赖的有效范围,而不是对象创建次数越少越好。
从对象持有的数据开始检查
对象是否保存当前用户、租户、请求参数或数据库上下文?这些数据通常不能跨请求随意共享。尤其要检查看似无状态的服务是否通过成员字段保存了临时值,避免并发请求相互覆盖。
长生命周期不能随意持有短生命周期依赖
单例长期持有请求作用域服务,会让依赖超出预期范围。后台任务需要作用域服务时,应显式建立合适的作用域,并在工作完成后释放。不要为绕过容器检查就把所有依赖一起改成单例。
线程安全需要独立考虑
即使一个对象可以长期存在,也不代表其内部集合和状态支持并发访问。使用锁、不可变数据或其他并发方案前,应明确读写模式和性能目标。容器负责创建与释放,不负责替业务实现线程安全。
用并发与生命周期边界验收
同时提交不同租户请求,检查数据不会串用;停止后台任务后核实依赖已释放;开启适用的作用域验证帮助发现错误。不要只用单线程的正常接口测试判断注册方式正确。
常见问题:Transient 一定不会有共享状态问题吗?
不一定。它仍可能依赖单例、静态字段或共享外部资源,必须沿完整依赖链检查。
技术参考:微软:依赖注入指南。具体接口与配置请结合使用版本核对。
将评估落实到你的系统
如果内部团队需要把这些约定落到可运行的工程中,可以通过微服务基础架构建设沟通接口、公共能力与交接范围,先以一个业务场景验证方案。