当前位置: 首页 > news >正文

(13)ASP.NET Core2.2 中的选项模式(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<MyOptions>(Configuration);
}

也可以使用自定义ConfigurationBuilder从设置文件加载选项配置时,确认基路径设置正确,添加到服务容器并绑定到配置:

var configBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true);
var config = configBuilder.Build();
services.Configure<MyOptions>(config);

以下页面模型通过IOptionsMonitor<TOptions>使用构造函数依赖关系注入来访问设置 (Pages/Index.cshtml.cs):

public class IndexModel
{public IndexModel(IOptionsMonitor<MyOptions> optionsAccessor){_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(IOptionsMonitor<MyOptions> optionsAccessor)
{_optionsAccessor = optionsAccessor;
}
private readonly IOptionsMonitor<MyOptions> _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<TOptions>服务。它通过MyOptionsWithDelegateConfig使用委托来配置绑定:

public void ConfigureServices(IServiceCollection services)
{// Example #2: Options bound and configured by a delegateservices.Configure<MyOptionsWithDelegateConfig>(myOptions =>{myOptions.Option1 = "value1_configured_by_delegate";myOptions.Option2 = 500;});
}

以下页面模型通过IOptionsMonitor<TOptions>使用构造函数依赖关系注入来访问设置 (Pages/Index.cshtml.cs):

public class IndexModel
{private readonly MyOptionsWithDelegateConfig _optionsWithDelegateConfig;public IndexModel(IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig){_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(IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig)
{_optionsAccessorWithDelegateConfig = optionsAccessorWithDelegateConfig;
}
private readonly IOptionsMonitor<MyOptionsWithDelegateConfig> _optionsAccessorWithDelegateConfig;
public IActionResult Index()
{IndexModel indexModel = new IndexModel(_optionsAccessorWithDelegateConfig);indexModel.OnGet();return View();
}

每次调用Configure都会将IConfigureOptions<TOptions>服务添加到服务容器。在前面的示例中,Option1和Option2的值同时在appsettings.json中指定,但Option1和Option2的值被配置的委托替代。当启用多个配置服务时,指定的最后一个配置源优于其他源,由其设置配置值。运行应用程序时,页面模型的OnGet方法返回显示选项类值的字符串。

4.子选项配置

将选项绑定到配置时,选项类型中的每个属性都将绑定到窗体property[:sub-property:]的配置键。例如,MyOptions.Option1属性将绑定到从appsettings.json中的option1属性读取的键Option1。在以下代码中,已向服务容器添加IConfigureOptions<TOptions>服务。它将MySubOptions绑定到appsettings.json文件的subsection部分:

public void ConfigureServices(IServiceCollection services)
{// Example #3: Suboptions// Bind options using a sub-section of the appsettings.json file.services.Configure<MySubOptions>(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<TOptions>使用构造函数依赖关系注入来访问设置(Pages/Index.cshtml.cs):

public class IndexModel
{private readonly MySubOptions _subOptions;public IndexModel(IOptionsMonitor<MySubOptions> subOptionsAccessor){_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(IOptionsMonitor<MySubOptions> subOptionsAccessor)
{_subOptionsAccessor = subOptionsAccessor;
}
private readonly IOptionsMonitor<MySubOptions> _subOptionsAccessor;
public IActionResult Index()
{IndexModel indexModel = new IndexModel(_subOptionsAccessor);indexModel.OnGet();return View();
}

5.通过IOptionsSnapshot重新加载配置数据

IOptionsSnapshot针对请求生命周期访问和缓存选项时,每个请求只能计算一次选项。以下示例演示如何在更改appsettings.json(Pages/Index.cshtml.cs)后创建新的 IOptionsSnapshot<TOptions>。在更改appsettings.json文件和重新加载配置之前,针对服务器的多个请求返回appsettings.json文件提供的配置键值:

public class IndexModel
{private readonly MyOptions _snapshotOptions;public IndexModel(IOptionsSnapshot<MyOptions> snapshotOptionsAccessor){_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<TOptions>.Configure:

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<MyOptions>("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<MyOptions>("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(IOptionsSnapshot<MyOptions> namedOptionsAccessor){_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(IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{_namedOptionsAccessor = namedOptionsAccessor;
}
private readonly IOptionsSnapshot<MyOptions> _namedOptionsAccessor;
public IActionResult Index()
{IndexModel indexModel = new IndexModel(_namedOptionsAccessor);indexModel.OnGet();return View();
}

6.1使用ConfigureAll方法配置所有选项

使用ConfigureAll方法可以配置所有选项实例。以下代码将针对包含公共值的所有配置实例配置Option1。将以下代码手动添加到Startup.ConfigureServices方法:

services.ConfigureAll<MyOptions>(myOptions => 
{myOptions.Option1 = "ConfigureAll replacement value";
});

在Home/Index控制器Action下调用IndexModel.OnGet方法返回包含选项值的字符串:


参考文献:
ASP.NET Core 中的选项模式https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/options?view=aspnetcore-9.0&viewFallbackFrom=aspnetcore-2.2#suboptions-configuration

http://www.dtcms.com/a/406332.html

相关文章:

  • 做公司网站需要准备什么苏州网站建设企业
  • giflib5.2.2 在Qt与VS C++中实现Gif缩放示例
  • 题解:AT_abc401_c [ABC401C] K-bonacci
  • 【OpenFeign】在 RuoYi 框架中优雅使用 OpenFeign:从原理到实践与踩坑总结
  • VMware虚拟机安装ubuntu
  • 因果推断落地:从CausalML到EconML,详解Uplift建模核心库
  • 备案个人网站做淘宝客wordpress能做企业站吗
  • 天玑与骁龙芯片:性能对决与选择指南
  • 【RustPython】 RustPython Cargo.toml 配置文件详解
  • 献县网站做映射后 内网无法通过域名访问网站
  • Go语言 对接全球股票K线API实战 - 以美股市场为例
  • Linux系统Nginx服务(四)
  • Linux to go Ubuntu 22.04 不匹配无线网卡 MT7925 的解决方法
  • Go语言在区块链开发中的应用场景详解
  • go的基础数据结构 slice源码阅读
  • 百度网盟推广 网站四川建设网有限责任公司官网
  • 破局渠道垄断:青蓝的流量入口变现路径
  • 【C++STL :string类 (二) 】从接口应用到内存模型的全面探索
  • 学做面包到什么网站网站点击按钮回到页面顶部怎么做
  • 领航 网站设计主机屋怎么做网站
  • 在VTK中实现相机自动绕轴旋转
  • 关于解决switch开关属性中active-value=“1“为数值形失败的问题
  • Seata 深度解析:微服务分布式事务管理的实践指南
  • LeetCode:53.课程表
  • 中国县域经济韧性(2006-2021)
  • MySQL零基础学习Day3——函数和约束
  • Bililive-go+cpolar:跨平台直播录制的远程管理方案
  • 飞马无人机正射/倾斜影像数据预处理
  • 2025 AI 技术跃迁与产业融合:从实验室到价值场
  • 济源网站建设价格蓝色系网站