• asp.net core之Options


    本文将介绍 ASP.NET Core 中的 Options 概念和使用方法。Options 是一种配置管理机制,可以将应用程序的配置信息从代码中分离出来,提高代码的可维护性和可测试性。我们将详细介绍如何定义 Options 类、注册 Options、使用 Options,并提供相应的示例代码。此外,我们还将对 IOptions、IOptionsSnapshot、IOptionsMonitor、IConfigureNamedOptions、OptionsBuilder、IValidateOptions、PostConfigureOptions 等相关接口和类进行说明,并给出使用场景示例。

    Options 概述#

    在 ASP.NET Core 中,Options 是一种配置管理机制,它允许将应用程序的配置信息从代码中分离出来,以提高代码的可维护性和可测试性。通过使用 Options,我们可以将配置信息封装到一个或多个 Options 类中,并通过依赖注入将其注入到需要使用配置的组件中。

    Options 提供了一种统一的方式来访问配置信息,而不需要直接访问配置文件或配置提供程序。它还支持配置的热更新,即在应用程序运行时修改配置后,可以自动应用新的配置值,而无需重新启动应用程序。

    定义 Options 类#

    在 ASP.NET Core 中,我们可以通过定义一个 Options 类来表示一组相关的配置信息。Options 类是一个普通的 C# 类,其中的属性对应配置的键值对。

    public class MyOptions
    {
        public string Option1 { get; set; }
        public int Option2 { get; set; }
    }
    

    在上面的示例中,我们定义了一个名为 MyOptions 的 Options 类,它包含了两个属性 Option1 和 Option2。
    在appsettings.json中添加配置:

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*",
      "MyOptions": {
        "Option1": "Test",
        "Option2": 123
      }
    }
    

    注册 Options#

    要在 ASP.NET Core 中使用 Options,我们需要将 Options 类注册到依赖注入容器中。可以通过在 ConfigureServices 方法中调用 services.Configure(Configuration.GetSection("SectionName")) 来完成注册。

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure(Configuration.GetSection("MyOptions"));
    }
    

    使用WebApplication则这样操作:

    builder.Services.Configure(builder.Configuration.GetSection("MyOptions"));
    

    在上面的示例中,我们将 MyOptions 类注册为一个 Options,并指定了配置文件中的配置节名称为 "MyOptions"。

    使用 Options#

    在需要使用配置的组件中,我们可以通过依赖注入将 Options 注入,并直接访问 Options 类的属性来获取配置值。

    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };
    
        private readonly MyOptions _options;
        private readonly ILogger _logger;
    
        public WeatherForecastController(ILogger logger, MyOptions options)
        {
            _logger = logger;
            _options = options;
        }
    
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable Get()
        {
            // 使用配置值
            var option1Value = _options.Option1;
            var option2Value = _options.Option2;
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
    

    在上面的示例中,我们通过构造函数注入了 IOptions,并在 WeatherForecastController中使用了配置值。
    image.png
    通过Debug我们可以看到正常获取值。

    IOptions、IOptionsSnapshot 和 IOptionsMonitor#

    在 ASP.NET Core 中,有三个主要的 Options 接口:IOptions、IOptionsSnapshot 和 IOptionsMonitor,它们在不同的场景下提供了不同的配置值获取方式。
    IOptions:在每次调用时返回相同的配置值,适用于获取配置值后不会发生变化的场景。
    IOptionsSnapshot:在每次调用时返回最新的配置值,适用于获取配置值可能会发生变化的场景。
    IOptionsMonitor:实时监控配置值的变化,并在配置值发生变化时提供新的配置值,适用于需要实时响应配置变化的场景。
    下面我们把Options分三种模式注入。

    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };
    
        private readonly MyOptions _options;
        private readonly MyOptions _options2;
        private MyOptions _options3;
        private readonly ILogger _logger;
    
        public WeatherForecastController(ILogger logger, IOptions options, IOptionsSnapshot options2, IOptionsMonitor options3)
        {
            _logger = logger;
            _options = options.Value;
            _options2 = options2.Value;
            _options3 = options3.CurrentValue;
            options3.OnChange(o => _options3 = options3.CurrentValue);
        }
        
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable Get()
        {
            // 使用配置值
            var option1Value = _options.Option1;
            var option2Value = _options.Option2;
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
    

    首次请求,可以看到三个内容都是一致的
    image.png

    接下来修改一下配置文件,注意,不需要重启服务。

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*",
      "MyOptions": {
        "Option1": "Test2222",
        "Option2": 123456
      }
    }
    
    

    再次请求,可以看到IOptionsSnapshot和IOptionsMonitor都发生了变化。


    image.png
    这里我们可以看到IOptionsMonitor获取内容不是Value,而是CurrentValue,因为他是实时发生更新变化的。如果我们也需要试试获取最新变化的值,则可以使用OnChange监听变化,然后重新给属性赋值。
    比如我们跑的后台任务,或者一些单例服务,在第一次构造器注入options之后就不会变化的场景,可以用这种方式的更新Options的值。

    IConfigureNamedOptions、OptionsBuilder 和 IValidateOptions#

    IConfigureNamedOptions:用于配置特定名称的 Options 对象。可以通过实现该接口来为特定的 Options 类提供配置。
    比如:

    builder.Services.Configure(builder.Configuration.GetSection("MyOptions"));
    builder.Services.Configure("Abcd",builder.Configuration.GetSection("MyOptions"));
    

    OptionsBuilder:用于配置 Options 对象。可以通过调用 Configure 方法来为 Options 类进行配置。

    builder.Services.AddOptions("OptionsBuilderOptions")
        .Configure(o => 
        {
            o.Option1 = "OptionsBuilderOptions"; 
            o.Option2 = 999; 
        })
        ;
    

    启动服务DEBUG检验一下,发现我们成功取到值了。
    image.png

    这里需要注意的是IOptions<>是没有Get的方法的,要获取对应名称的Options只能通过IOptionsSnapshot<>或IOptionsMonitor<>。

    IValidateOptions:用于验证 Options 对象的配置。可以通过实现该接口来对 Options 进行验证。

    public class MyOptionsValidator : IValidateOptions<MyOptions>
    {
        public ValidateOptionsResult Validate(string name, MyOptions options)
        {
            // 验证 Options 的配置
            if (options.Option1 == null)
            {
                return ValidateOptionsResult.Fail("Option1 must be specified.");
            }
            return ValidateOptionsResult.Success;
        }
    }
    
    builder.Services.AddOptions("ValidateOptions")
        .Configure(o =>
        {
            o.Option1 = null;
            o.Option2 = 999;
        })
        ;
    builder.Services.AddSingleton                              , MyOptionsValidateOptions>();
    
    public WeatherForecastController(ILogger logger, IOptions options, IOptionsSnapshot options2, IOptionsMonitor options3)
            {
                _logger = logger;
                _options = options.Value;
                _options2 = options2.Value;
                _options3 = options3.CurrentValue;
                options3.OnChange(o => _options3 = options3.CurrentValue);
    
                var nameOption = options2.Get("Abcd");
                var nameOption2 = options3.Get("OptionsBuilderOptions");
                var nameOption3 = options3.Get("ValidateOptions");
            }
    

    启动服务,发出请求,可以发现报错了。
    image.png

    结论#

    通过合理使用 Options,我们可以更好地管理和配置 ASP.NET Core 应用程序。本文详细介绍了 Options 的概念和使用方法,并对相关接口和类进行了说明和示例。通过使用 Options,我们可以将配置信息从代码中分离出来,提高代码的可维护性和可测试性,同时还能实现配置的热更新和实时响应配置变化。

    欢迎进群催更。

  • 相关阅读:
    Python3 错误和异常
    JMeter界面和字体的调整
    数据结构第一章:部分答案
    了解高防服务器的工作原理
    uniapp中实现瀑布流 短视频页面展示
    练习题(2024/4/)
    mysql 命令行安装
    翻译专业论文选题有哪些值得写的方向?
    C++ STL库 list(链表)
    P1631 序列合并,思维,优先队列
  • 原文地址:https://www.cnblogs.com/fanshaoO/p/17592993.html