如何获取IServiceProvider实例?优化DbContext注入避免重复AWS调用
解决方案
你遇到的核心问题是服务注册阶段(AddBindings执行时)还未生成最终的IServiceProvider,所以无法直接像示例那样获取。针对重复调用AWS接口的优化需求,推荐以下两种靠谱的实现方式:
方式一:将连接字符串注册为单例服务(推荐)
这种方式既避免重复调用AWS接口,又符合DI的设计原则:
public override void AddBindings() { // 1. 先注册连接字符串为单例:仅第一次解析时调用AWS接口 Services.AddSingleton(sp => sp.GetRequiredService<ISecretManager>().Get("TestApi") ); // 2. 注册DbContext时直接注入预解析好的连接字符串 Services.AddScoped<IDbContext>(sp => new DbContext(sp.GetRequiredService<string>()) ); }
原理:连接字符串会在第一次被请求时(即第一次创建DbContext时)通过IServiceProvider解析一次,之后复用这个单例字符串,不会再调用AWS接口。
方式二:构建临时ServiceProvider(不推荐,仅特殊场景使用)
如果必须在服务注册阶段提前获取连接字符串,可以构建临时的ServiceProvider,但要注意临时容器的服务生命周期可能和最终容器不一致,仅适合ISecretManager是单例的情况:
public override void AddBindings() { // 构建临时ServiceProvider来解析ISecretManager using var tempProvider = Services.BuildServiceProvider(); var connection = tempProvider.GetRequiredService<ISecretManager>().Get("TestApi"); // 注册DbContext时复用这个连接字符串 Services.AddScoped<IDbContext>(_ => new DbContext(connection)); }
注意:这种方式会提前创建ISecretManager实例,如果它是单例,临时容器和最终容器会共用同一个实例;如果是其他生命周期,会创建两个不同的实例,可能导致资源浪费或状态不一致。
关键说明
在AddBindings方法执行期间,DI容器处于服务注册阶段,还未完成最终的构建,因此不存在全局可用的IServiceProvider实例。必须通过上述两种方式来提前获取所需的依赖值。
内容的提问来源于stack exchange,提问作者Master
相关产品推荐
相关产品推荐

