首页 新闻 会员 周边 捐助

.NET: ConfigureServices 中究竟能不能使用 BuildServiceProvider

0
悬赏园豆:50 [已解决问题] 解决于 2023-01-29 10:18

Startup.ConfigureServices 中使用 services.BuildServiceProvider 的场景之一是在实现基于 IServiceCollection 的扩展方法时,可以不需要调用方传参 IConfiguration,比如下面的扩展方法实现

public static IServiceCollection AddEnyimMemcached(
    this IServiceCollection services,
    string sectionKey = "enyimMemcached",
    bool asDistributedCache = true)
{
    var config = services.BuildServiceProvider().GetRequiredService<IConfiguration>();
    return services.AddEnyimMemcached(config.GetSection(sectionKey), asDistributedCache);
}

但在微软官方文档 Dependency injection guidelines 的 recommendations 中有一条

Avoid calls to BuildServiceProvider in ConfigureServices. Calling BuildServiceProvider typically happens when the developer wants to resolve a service in ConfigureServices.

文档中为什么给出这样的建议?如果使用了,有什么副作用?

dudu的主页 dudu | 高人七级 | 园豆:31030
提问于:2023-01-28 13:58
< >
分享
最佳答案
1

可以参考类似这样, 然后改造AddEnyimMemcached方法.
services.AddScoped<>(sp=> new xxx(sp.GetService<IConfiguration>()))

副作用情况:
会有多个IConfiguration的单例实例.
services.BuildServiceProvider() 这里会有一个, 在整个程序生命周期内还有一个.
所以: 如果有自定义的单例类要用到, 然后这个单例类里面又有一些不支持多次new的逻辑. 大概就会有冲突......

BUG情况:
如果有用到类似AddJsonStream 添加configuration provider, 那就会有问题, stream只支持读取一次......

收获园豆:50
czd890 | 专家六级 |园豆:14482 | 2023-01-28 22:54

如果直接在 Startup.ConfigureServices 中写 services.BuildServiceProvider(),VS 会出现下面的警告

Calling 'BuildServiceProvider' from application code results in an additional copy of singleton services being created. Consider alternatives such as dependency injecting services as parameters to 'Configure'.

AddEnyimMemcached 是扩展方法,所以没有触发这个警告

dudu | 园豆:31030 (高人七级) | 2023-01-29 08:46

@dudu:
改造是针对 可以不需要调用方传参 IConfiguration, 类似下面的代码.

public static IServiceCollection AddEnyimMemcached(
    this IServiceCollection services,
    string sectionKey = "enyimMemcached",
    bool asDistributedCache = true)
{
    services.Add<T>(sp=>new T(sp.GetService<IConfiguration>().GetSection(sectionKey),asDistributedCache ))

}

多次 BuildServiceProvider 是不靠谱的方案😂

czd890 | 园豆:14482 (专家六级) | 2023-01-29 10:22

@czd890: 我按照这个方法改进一下试试

dudu | 园豆:31030 (高人七级) | 2023-01-29 10:27

@dudu: 改进中遇到的问题 https://q.cnblogs.com/q/142503/

dudu | 园豆:31030 (高人七级) | 2023-01-29 12:10

@dudu: 又在 stackoverflow 时发展一个参考:Resolving instances with ASP.NET Core DI from within ConfigureServices

dudu | 园豆:31030 (高人七级) | 2023-01-29 17:08
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册