在.NET 6的Scoped服务中使用Lazy<T>存储Token的持久化疑问
Scoped服务中静态Lazy的Token持久化问题
核心疑问
若将Token存储为Lazy<T>对象,且在值工厂内获取Token:
- Token值会跨多个请求持久化吗?
- 还是因底层服务为Scoped,每个请求的
Lazy都从null值开始?
代码示例
初始化Lazy的逻辑
_token = new Lazy<Token>(() => { var token = new Token(); var task = Task.Run(async () => { var response = await Login(); token.AccessToken = response.AccessToken; }); task.Wait(); return token; });
服务构造函数(注:原代码存在语法错误,静态字段需声明在类级别)
public class MyService : IMyService { // 静态字段需声明在类作用域,而非构造函数内 private static Lazy<Token> _token; public MyService() { if (_token is { IsValueCreated: false }) { // 执行上述初始化Lazy的逻辑 } } }
服务注册(Scoped)
services.AddScoped<IMyService, MyService>();
结论
_token是静态字段,属于MyService类本身,而非类的实例。即使MyService注册为Scoped(每个请求创建一个新实例),静态字段在整个应用域(AppDomain)内只有一份副本。- 第一次创建
MyService实例时,_token会被初始化,值工厂会执行一次并获取Token。 - 后续所有请求创建的
MyService实例,都会复用这个已经初始化完成的静态_token,值工厂不会再执行。 - 最终结果:Token会跨多个请求持久化,直到应用重启或静态字段被CLR回收(几乎不会发生)。
额外提示
原代码中构造函数内声明静态字段的写法存在语法错误,静态字段必须声明在类的作用域下,不能放在构造函数内部,否则无法通过编译。
内容的提问来源于stack exchange,提问作者GeorgeR
相关产品推荐
相关产品推荐

