在Program.cs中访问带依赖的单例StateService以获取令牌
解决方案:在Program.cs中获取令牌并注入解耦的TestService
核心思路
不要手动实例化StateService,而是从依赖注入容器中获取已注册的单例实例,同时通过委托/工厂模式让TestService与StateService解耦,避免直接依赖。
方案1:同步令牌场景 - 工厂模式注册
如果StateService的令牌获取是同步方法(如GetToken()),可以直接在注册ITestService时,通过服务提供者拿到StateService实例并提取令牌:
// Program.cs builder.Services.AddSingleton<StateService>(); // 已注册的单例 builder.Services.AddSingleton<ITestService>(provider => { // 从容器中获取已初始化的StateService单例 var stateService = provider.GetRequiredService<StateService>(); // 提取令牌 var token = stateService.GetToken(); // 传入令牌创建TestService实例 return new TestService(token); });
方案2:异步令牌场景 - 委托延迟获取(推荐)
由于StateService依赖IJSRuntime,令牌获取通常是异步方法(如GetTokenAsync()),此时不建议在启动阶段同步阻塞获取,而是让TestService通过委托在需要时异步获取令牌,同时保持解耦:
第一步:修改TestService构造函数,接受令牌获取委托
public class TestService : ITestService { private readonly Func<Task<string>> _getTokenAsync; // 用委托替代直接依赖StateService,实现解耦 public TestService(Func<Task<string>> getTokenAsync) { _getTokenAsync = getTokenAsync; } public async Task ExecuteWithToken() { // 需要时再异步获取令牌 var token = await _getTokenAsync(); // 执行业务逻辑 } }
第二步:在Program.cs中注册ITestService
// Program.cs builder.Services.AddSingleton<StateService>(); builder.Services.AddSingleton<ITestService>(provider => { var stateService = provider.GetRequiredService<StateService>(); // 传入异步获取令牌的委托 return new TestService(() => stateService.GetTokenAsync()); });
为什么手动实例化StateService会失败?
StateService依赖IJSRuntime,而IJSRuntime是Blazor框架自动注册到依赖注入容器中的服务,手动实例化时无法自动注入该依赖,必须通过IServiceProvider.GetRequiredService<T>从容器中获取已完成依赖注入的StateService实例。
内容的提问来源于stack exchange,提问作者Musaffar Patel
相关产品推荐
相关产品推荐

