ASP.NET|ASP.NET Core中的Options选项模式
1.前言
选项(Options)模式是对配置(Configuration)的功能的延伸。在12章(ASP.NET Core中的配置二)Configuration中有介绍过该功能(绑定到实体类、绑定至对象图、将数组绑定至类)而选项模式又有个选项类(TOptions),该选项类作用是指:把选项类中的属性与配置来源中的键关联起来。举个例,假设json文件有个Option1键,选项类中也有个叫Option1的属性名,经过选项配置,这样就能把json中的键的值映射到选项类属性值中。也可以理解在项目应用中,把一个json文件序列化到.net类。
2.常规选项配置
选项类必须为包含公共无参数构造函数的非抽象类。在appsettings.json文件中添加option1、option2、subsection的配置:
{"option1": "value1_from_json","option2": -1,"subsection": {"suboption1": "subvalue1_from_json","suboption2": 200},"Logging": {"LogLevel": {"Default": "Warning"}},"AllowedHosts": "*"}
新建MyOptions类(Models/MyOptions.cs),以下类MyOptions具有三种属性:Option1和 Option2。设置默认值为可选,但以下示例中的类构造函数设置了Option1的默认值。Option2具有通过直接初始化属性设置的默认值:
public class MyOptions{public MyOptions(){// Set default value.Option1 = "value1_from_ctor"; }public string Option1 { get; set; }public int Option2 { get; set; } = 5; }
而MyOptions类通过Configure添加到服务容器并绑定到配置:
public void ConfigureServices(IServiceCollection services){// Example #1: General configuration// Register the Configuration instance which MyOptions binds against.services.Configure(Configuration); }
也可以使用自定义ConfigurationBuilder从设置文件加载选项配置时,确认基路径设置正确,添加到服务容器并绑定到配置:
var configBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true); var config = configBuilder.Build(); services.Configure(config);
以下页面模型通过IOptionsMonitor
public class IndexModel{public IndexModel(IOptionsMonitoroptionsAccessor){_options = optionsAccessor.CurrentValue; }private readonly MyOptions _options; public void OnGet(){// Example #1: Simple optionsvar option1 = _options.Option1; var option2 = _options.Option2; var simpleOptions = $"option1 = {option1}, option2 = {option2}"; }}
在Home/Index控制器Action下调用IndexModel.OnGet方法返回包含选项值的字符串:
public HomeController(IOptionsMonitoroptionsAccessor){_optionsAccessor = optionsAccessor; }private readonly IOptionsMonitor _optionsAccessor; public IActionResult Index(){IndexModel indexModel = new IndexModel(_optionsAccessor); indexModel.OnGet(); return View(); }
文章图片
3.通过委托配置简单选项 使用委托设置选项值。此示例应用程序使用新建MyOptionsWithDelegateConfig类 (Models/MyOptionsWithDelegateConfig.cs):
public class MyOptionsWithDelegateConfig{public MyOptionsWithDelegateConfig(){// Set default value.Option1 = "value1_from_ctor"; }public string Option1 { get; set; }public int Option2 { get; set; } = 5; }
向服务容器添加IConfigureOptions
public void ConfigureServices(IServiceCollection services){// Example #2: Options bound and configured by a delegateservices.Configure(myOptions =>{myOptions.Option1 = "value1_configured_by_delegate"; myOptions.Option2 = 500; }); }
以下页面模型通过IOptionsMonitor
public class IndexModel{private readonly MyOptionsWithDelegateConfig _optionsWithDelegateConfig; public IndexModel(IOptionsMonitoroptionsAccessorWithDelegateConfig){_optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue; }public void OnGet(){// Example #2: Options configured by delegatevar delegate_config_option1 = _optionsWithDelegateConfig.Option1; var delegate_config_option2 = _optionsWithDelegateConfig.Option2; var simpleOptionsWithDelegateConfig =$"delegate_option1 = {delegate_config_option1}, " +$"delegate_option2 = {delegate_config_option2}"; }}
在Home/Index控制器Action下调用IndexModel.OnGet方法返回包含选项值的字符串:
public HomeController(IOptionsMonitoroptionsAccessorWithDelegateConfig){_optionsAccessorWithDelegateConfig = optionsAccessorWithDelegateConfig; }private readonly IOptionsMonitor _optionsAccessorWithDelegateConfig; public IActionResult Index(){IndexModel indexModel = new IndexModel(_optionsAccessorWithDelegateConfig); indexModel.OnGet(); return View(); }
文章图片
每次调用Configure都会将IConfigureOptions
4.子选项配置 将选项绑定到配置时,选项类型中的每个属性都将绑定到窗体property[:sub-property:]的配置键。例如,MyOptions.Option1属性将绑定到从appsettings.json中的option1属性读取的键Option1。在以下代码中,已向服务容器添加IConfigureOptions
public void ConfigureServices(IServiceCollection services){// Example #3: Suboptions// Bind options using a sub-section of the appsettings.json file.services.Configure(Configuration.GetSection("subsection")); }
新建MySubOptions类(Models/MySubOptions.cs)将属性SubOption1和SubOption2定义为保留选项值:
public class MySubOptions{public MySubOptions(){// Set default values.SubOption1 = "value1_from_ctor"; SubOption2 = 5; }public string SubOption1 { get; set; }public int SubOption2 { get; set; }}
以下页面模型通过IOptionsMonitor
public class IndexModel{private readonly MySubOptions _subOptions; public IndexModel(IOptionsMonitorsubOptionsAccessor){_subOptions = subOptionsAccessor.CurrentValue; }public void OnGet(){// Example #3: Suboptionsvar subOption1 = _subOptions.SubOption1; var subOption2 = _subOptions.SubOption2; var subOptions = $"subOption1 = {subOption1}, subOption2 = {subOption2}"; }}
在Home/Index控制器Action下调用IndexModel.OnGet方法返回包含选项值的字符串:
public HomeController(IOptionsMonitorsubOptionsAccessor){_subOptionsAccessor = subOptionsAccessor; }private readonly IOptionsMonitor _subOptionsAccessor; public IActionResult Index(){IndexModel indexModel = new IndexModel(_subOptionsAccessor); indexModel.OnGet(); return View(); }
文章图片
5.通过IOptionsSnapshot重新加载配置数据 IOptionsSnapshot针对请求生命周期访问和缓存选项时,每个请求只能计算一次选项。以下示例演示如何在更改appsettings.json(Pages/Index.cshtml.cs)后创建新的 IOptionsSnapshot
public class IndexModel{private readonly MyOptions _snapshotOptions; public IndexModel(IOptionsSnapshotsnapshotOptionsAccessor){_snapshotOptions = snapshotOptionsAccessor.Value; }public void OnGet(){// Example #5: Snapshot optionsvar snapshotOption1 = _snapshotOptions.Option1; var snapshotOption2 = _snapshotOptions.Option2; var snapshotOptions = $"snapshot option1 = {snapshotOption1}, " + $"snapshot option2 = {snapshotOption2}"; }}
下面显示从appsettings.json文件加载的初始option1和option2值:
snapshot option1 = value1_from_json, snapshot option2 = -1
将appsettings.json文件中的值更改为value1_from_json UPDATED和200。保存appsettings.json 文件。刷新浏览器,查看更新的选项值:
snapshot option1 = value1_from_json UPDATED, snapshot option2 = 200
6.包含IConfigureNamedOptions的命名选项支持 命名选项支持允许应用程序在命名选项配置之间进行区分。命名选项通过OptionsServiceCollectionExtensions.Configure进行声明,其调用扩展方法ConfigureNamedOptions
public void ConfigureServices(IServiceCollection services){// Example #6: Named options (named_options_1)// Register the ConfigurationBuilder instance which MyOptions binds against.// Specify that the options loaded from configuration are named// "named_options_1".services.Configure("named_options_1", Configuration); // Example #6: Named options (named_options_2)// Specify that the options loaded from the MyOptions class are named// "named_options_2".// Use a delegate to configure option values.services.Configure ("named_options_2", myOptions =>{myOptions.Option1 = "named_options_2_value1_from_action"; }); }
通过OnGet(Pages/Index.cshtml.cs)访问命名选项:
public class IndexModel{private readonly MyOptions _named_options_1; private readonly MyOptions _named_options_2; public IndexModel(IOptionsSnapshotnamedOptionsAccessor){_named_options_1 = namedOptionsAccessor.Get("named_options_1"); _named_options_2 = namedOptionsAccessor.Get("named_options_2"); }public void OnGet(){// Example #6: Named optionsvar named_options_1 =$"named_options_1: option1 = {_named_options_1.Option1}, " +$"option2 = {_named_options_1.Option2}"; var named_options_2 =$"named_options_2: option1 = {_named_options_2.Option1}, " +$"option2 = {_named_options_2.Option2}"; var namedOptions = $"{named_options_1} {named_options_2}"; }}
在Home/Index控制器Action下调用IndexModel.OnGet方法返回包含选项值的字符串:
public HomeController(IOptionsSnapshotnamedOptionsAccessor){_namedOptionsAccessor = namedOptionsAccessor; }private readonly IOptionsSnapshot _namedOptionsAccessor; public IActionResult Index(){IndexModel indexModel = new IndexModel(_namedOptionsAccessor); indexModel.OnGet(); return View(); }
文章图片
使用ConfigureAll方法配置所有选项
使用ConfigureAll方法可以配置所有选项实例。以下代码将针对包含公共值的所有配置实例配置Option1。将以下代码手动添加到Startup.ConfigureServices方法:
services.ConfigureAll(myOptions =>{myOptions.Option1 = "ConfigureAll replacement value"; });
在Home/Index控制器Action下调用IndexModel.OnGet方法返回包含选项值的字符串:
文章图片
【ASP.NET|ASP.NET Core中的Options选项模式】以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
推荐阅读
- java8中的Collectors.groupingBy用法详解
- ASP.NET|ASP.NET Core中MVC模式实现路由一
- React中的renderProps和childrenProps
- Git 中的算法-最近公共祖先
- 数据分析在生活中的应用- 女人的衣柜里为什么总是少一件衣服
- 计算机网络|计算机网络中的NET与应用中的.NET
- 详解Java中的mapstruct插件使用
- ASP.NET|ASP.NET Core应用启动Startup类简介
- 委托代码详解
- 如何科学衡量广告投放效果(HMS|如何科学衡量广告投放效果?HMS Core分析服务助您科学归因)