在 asp.net Core 中配置服务注册时的依赖注入访问 (3+)

Posted

技术标签:

【中文标题】在 asp.net Core 中配置服务注册时的依赖注入访问 (3+)【英文标题】:Dependency Injection Access While Configuring Service Registrations in asp.net Core (3+) 【发布时间】:2021-11-28 04:59:31 【问题描述】:

我有一些案例,我想根据在依赖注入容器中注册的对象来配置服务。 例如,我为 WS Federation 注册了以下内容:

authenticationBuilder.AddWsFederation((options) =>                
       options.MetadataAddress = "...";
       options.Wtrealm = "...";                
       options.[...]=...
);

在上述情况下,我的目标是使用配置对象,该对象可通过 DI 容器来配置 WsFederation-middleware。 在我看来,IPostConfigureOptions<> 是要走的路,但直到现在,我还没有找到实现这一目标的方法。 这是怎么做到的,还是不可能的?

【问题讨论】:

感谢采纳答案,你最后选择了哪种方式? (只是想知道我未经测试的代码是否有效) 后者,但我也测试了第一个,但是没有访问我的 DI 对象。第一个我在注册时也遇到了问题,但我不介意,因为后者正是我想要的。 【参考方案1】:

I(Post)ConfigureOptions<T> 方式见https://andrewlock.net/simplifying-dependency-injection-for-iconfigureoptions-with-the-configureoptions-helper/,但我觉得这种方式太麻烦了。

我一般使用这种模式:

// Get my custom config section
var fooSettingsSection = configuration.GetSection("Foo");

// Parse it to my custom section's settings class
var fooSettings = fooSettingsSection.Get<FooSettings>() 
    ?? throw new ArgumentException("Foo not configured");

// Register it for services who ask for an IOptions<FooSettings>
services.Configure<FooSettings>(fooSettings);

// Use the settings instance
services.AddSomeOtherService(options => 
    ServiceFoo = fooSettings.ServiceFoo;
)

更明确一点,但您将所有配置和 DI 代码放在一个地方。

当然,这完全绕过了I(Post)ConfigureOptions&lt;T&gt;,所以如果之后有其他代码使用这些接口修改FooSettings,我的代码不会注意到它,因为它是直接从配置文件中读取的。鉴于我控制 FooSettings 及其用户,这对我来说没问题。


如果您确实想使用该界面,这应该是方法:

首先,注册您要从中提取设置的自定义配置部分:

var fooSettingsSection = configuration.GetSection("Foo");
services.Configure<FooSettings>(fooSettingsSection);

然后,创建一个选项配置器:

public class ConfigureWSFedFromFooSettingsOptions 
    : IPostConfigureOptions<Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions>

    private readonly FooSettings _fooSettings;

    public ConfigureWSFedFromFooSettingsOptions(IOptions<FooSettings> fooSettings)
    
        _fooSettings = fooSettings.Value;
    

    public void Configure(WsFederationOptions options)
    
        options.MetadataAddress = _fooSettings.WsFedMetadataAddress;
        options.Wtrealm = _fooSettings.WsFedWtRealm;
    

最后将这些东西链接在一起:

services.AddTransient<IPostConfigureOptions<WsFederationOptions>, ConfigureWSFedFromFooSettingsOptions>();

配置器将注入您的IOptions&lt;FooSettings&gt;,从appsettings 实例化,然后用于进一步配置WsFederationOptions

【讨论】:

我确实需要 IPostConfigureOptions。,如您的示例中所示的 IConfigureOptions 不会,但其余的工作就像一个魅力,非常感谢。

以上是关于在 asp.net Core 中配置服务注册时的依赖注入访问 (3+)的主要内容,如果未能解决你的问题,请参考以下文章

替换 ASP.NET Core 内置 DI 容器中的服务注册?

[目录] ASP.Net Core 微服务搭建网站

ASP.NET Core在Azure Kubernetes Service中的部署和管理

在 Asp.Net Core 5.0 中注册 HttpClient 时注入 ILogger

asp.net core2 mvc 基础教程--服务注册和管道

Asp.Net Core 空白模板搭建Mvc架构