首页 新闻 会员 周边 捐助

ASP.NET Core: 如何通过依赖注入的方式获取 IConfiguration 绑定到 Options

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

在 实现 ServiceCollection extension methods 时,如果需要 bind Options,通常的做法是增加 IConfiguration 类型的参数,让调用方传入。

为了追求代码的简洁,我们有时希望减少这个传参操作,于是直接在扩展方法中获取 IConfiguration,从而误入歧途,详见 https://q.cnblogs.com/q/142496/

var config = services.BuildServiceProvider().GetRequiredService<IConfiguration>();

为了避开上面的坑,只能弃用 BuildServiceProvider,但我们又不想修改所有调用方的代码,让其传入 IConfiguration。

public static IServiceCollection AddEnyimMemcached(
    this IServiceCollection services,
    IConfiguration configuration,
    string sectionKey = "enyimMemcached",
    bool asDistributedCache = true)
{
    var section = configuration.GetSection(sectionKey);
    return services.AddEnyimMemcachedInternal(
        s => s.Configure<MemcachedClientOptions>(section), asDistributedCache);
}

传入 IConfiguration 的目的就是为了绑定上面的 MemcachedClientOptions,如果我们能够实现不需要调方传入而通过 Dependency Injection 容器解析出 IConfiguration,就能实现既能避开 BuildServiceProvider 的坑又不需要调用方修改任何代码的美好愿望。

请问如何实现?

dudu的主页 dudu | 高人七级 | 园豆:29363
提问于:2023-01-29 12:09
< >
分享
最佳答案
1
 services.AddOptions<MemcachedClientOptions>().BindConfiguration(sectionKey);
收获园豆:50
czd890 | 专家六级 |园豆:14488 | 2023-01-29 12:26

赞!蜻蜓点水般地解决了问题

dudu | 园豆:29363 (高人七级) | 2023-01-29 13:35

如果不是你的回答及时解救,我差点尝试采用 IConfigureOptions<TOptions> 解决这个问题,就是 How To Use The Options Pattern In ASP.NET Core 7 这篇博文中的方法

dudu | 园豆:29363 (高人七级) | 2023-01-29 13:39

@dudu: 他们的底层其实都是一样的, 最终都是 AddSingleton<IConfigureOptions<TOptions>>, 2条路, 一模一样的目的地.

实现自己的IConfigureOptions 有更复杂的绑定逻辑的时候用可能更合适.

czd890 | 园豆:14488 (专家六级) | 2023-01-29 13:42

今天在写代码时的进一步使用

public static IHttpClientBuilder AddBlogClient(
    this IServiceCollection services,
    string configName = "blogClient",
    Action<BlogClientOptions>? configureOptions = null)
{
    services.AddOptions<BlogClientOptions>()
        .BindConfiguration(configName)
        .PostConfigure(options => configureOptions?.Invoke(options));
    services.AddTransient<BlogClient>();

    return services.AddRefitClient<IBlogPostClient>()
        .ConfigureHttpClient((sp, client) =>
            client.BaseAddress = new Uri(
                sp.GetRequiredService<IOptions<BlogClientOptions>>().Value.BaseAddress));
}
dudu | 园豆:29363 (高人七级) | 2023-01-31 12:39
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册