c# - 为什么即使未注册 IOptions 也会得到解决

标签 c# asp.net-core dependency-injection .net-core asp.net-core-configuration

在我的 .NET Core 项目中,我在 Configure 方法中有以下设置:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    //services.AddOptions<UploadConfig>(Configuration.GetSection("UploadConfig"));
}

我没有注册任何IOptions,我正在将它注入(inject) Controller

[Route("api/[controller]")]
[ApiController]
public class HelloWorldController : ControllerBase
{
    public HelloWorldController(IOptions<UploadConfig> config)
    {
        var config1 = config.Value.Config1;
    }
 }

IOptions 正在使用默认实例进行解析,只有当我尝试使用它时(以及当我希望该值不为 null 时)我才会知道错误。

我能否以某种方式让它失败,说明实例类型未注册或类似的东西?我只想尽早发现错误。

最佳答案

选项框架由默认的主机构建器作为其设置的一部分进行设置,因此您不需要 AddOptions()你自己。然而,这也确保您可以使用 IOptions<T>无论你想去哪里,因为框架会为你提供准确的选项对象。

选项的工作方式是框架总是会给你一个 T (只要它能构造一个)。当您使用例如设置配置时 AddOptions<T> Configure<T> ,实际发生的是为该类型注册配置action T .当 IOptions<T>稍后解决,所有这些已注册的操作将按照它们注册的顺序运行。

这意味着配置选项类型是有效的。在这种情况下,将使用对象的默认值。当然,这也意味着你无法检测自己是否真的配置了options类型,配置是否真的有效。这通常必须在您使用这些值时完成。

例如,如果您需要 Config1要配置,你应该明确地寻找它:

public HelloWorldController(IOptions<UploadConfig> config)
{
    if (string.IsNullOrEmpty(config.Value.Config1))
        throw ArgumentException("Config1 is not configured properly");
}

另一种方法是使用 OptionsBuilder.Validate 为类型注册一个验证操作 .当您解析选项对象以验证包含的值时,将自动调用它。这样,您就可以在中央位置设置验证:

services.AddOptions<UploadConfig>()
    .Bind(Configuration.GetSection("UploadConfig"))
    .Validate(c => !string.IsNullOrEmpty(c.Config1));

不幸的是,这也意味着您只能在实际使用这些值时检测到这些问题,如果您没有彻底测试您的应用程序,可能会错过这些问题。解决这个问题的一种方法是在应用程序启动时解析选项并在那里验证它们。

例如,您可以只注入(inject) IOptions<T>在您的初创公司中 Configure方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IOptions<UploadConfig> uploadOptions)
{
    // since the options are injected here, they will be constructed and automatically
    // validated if you have configured a validate action

    // …
    app.UseMvc();
}

或者,如果您有多个要验证的选项,并且想要运行不适合验证操作的逻辑,您还可以创建一个验证它们的服务:

public class OptionsValidator
{
    private readonly IOptions<UploadConfig> uploadOptions;
    public OptionsValidator(IOptions<UploadConfig> uploadOptions)
    {
        _uploadOptions = uploadOptions;
    }

    public void Validate()
    {
        if (string.IsNullOrEmpty(_uploadOptions.Value.Config1))
            throw Exception("Upload options are not configured properly");
    }
}

然后将其注入(inject)您的 Configure :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, OptionsValidator optionsValidator)
{
    // validate options explicitly
    optionsValidator.Validate();

    // …
    app.UseMvc();
}

无论您做什么,请记住,默认情况下,配置源配置为支持在运行时更新配置。因此,您总会遇到配置在运行时暂时无效的情况。

关于c# - 为什么即使未注册 IOptions 也会得到解决,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55074806/

相关文章:

c# - 没有指定 authenticationScheme,也没有找到 DefaultChallengeScheme Cookies Authentication

asp.net - Ocelot 的文档 - 身份验证

WCF依赖注入(inject)和抽象工厂

c# - XNA 3D 点云

c# - 刷新表单后如何保留绘制的形状?

c# - 在 ToolStripButton 上使用 ImageList 时图像失真

c# - 如何在 ASP.NET Core 中手动注册 Mediatr 处理程序?

c# - 遍历树时查找节点

angular - 可配置的 Angular 9 模块

javascript - 鉴于 ES2015、依赖注入(inject)和库抽象,我理想的模块在 2016 年应该是什么样子?