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<MyOptions>(Configuration.GetSection("MyOptions"));
}
使用WebApplication则这样操作:
builder.Services.Configure<MyOptions>(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<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger, MyOptions options)
{
_logger = logger;
_options = options;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> 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中使用了配置值。
通过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<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IOptions<MyOptions> options, IOptionsSnapshot<MyOptions> options2, IOptionsMonitor<MyOptions> options3)
{
_logger = logger;
_options = options.Value;
_options2 = options2.Value;
_options3 = options3.CurrentValue;
options3.OnChange(o => _options3 = options3.CurrentValue);
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> 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();
}
}
首次请求,可以看到三个内容都是一致的
接下来修改一下配置文件,注意,不需要重启服务。
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"MyOptions": {
"Option1": "Test2222",
"Option2": 123456
}
}
再次请求,可以看到IOptionsSnapshot和IOptionsMonitor都发生了变化。

这里我们可以看到IOptionsMonitor获取内容不是Value,而是CurrentValue,因为他是实时发生更新变化的。如果我们也需要试试获取最新变化的值,则可以使用OnChange监听变化,然后重新给属性赋值。
比如我们跑的后台任务,或者一些单例服务,在第一次构造器注入options之后就不会变化的场景,可以用这种方式的更新Options的值。
IConfigureNamedOptions、OptionsBuilder 和 IValidateOptions
IConfigureNamedOptions:用于配置特定名称的 Options 对象。可以通过实现该接口来为特定的 Options 类提供配置。
比如:
builder.Services.Configure<MyOptions>(builder.Configuration.GetSection("MyOptions"));
builder.Services.Configure<MyOptions>("Abcd",builder.Configuration.GetSection("MyOptions"));
OptionsBuilder:用于配置 Options 对象。可以通过调用 Configure 方法来为 Options 类进行配置。
builder.Services.AddOptions<MyOptions>("OptionsBuilderOptions")
.Configure(o =>
{
o.Option1 = "OptionsBuilderOptions";
o.Option2 = 999;
})
;
启动服务DEBUG检验一下,发现我们成功取到值了。
这里需要注意的是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<MyOptions>("ValidateOptions")
.Configure(o =>
{
o.Option1 = null;
o.Option2 = 999;
})
;
builder.Services.AddSingleton<IValidateOptions
<MyOptions>, MyOptionsValidateOptions>();
public WeatherForecastController(ILogger<WeatherForecastController> logger, IOptions<MyOptions> options, IOptionsSnapshot<MyOptions> options2, IOptionsMonitor<MyOptions> 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");
}
启动服务,发出请求,可以发现报错了。
结论
通过合理使用 Options,我们可以更好地管理和配置 ASP.NET Core 应用程序。本文详细介绍了 Options 的概念和使用方法,并对相关接口和类进行了说明和示例。通过使用 Options,我们可以将配置信息从代码中分离出来,提高代码的可维护性和可测试性,同时还能实现配置的热更新和实时响应配置变化。
欢迎进群催更。

asp.net core之Options的更多相关文章
- asp.net core选项Options模块的笔记
这篇博客是写给自己看的.已经不止一次看到AddOptions的出现,不管是在.net core源码还是别人的框架里面,都充斥着AddOptions.于是自己大概研究了下,没有深入,因为,我的功力还是不 ...
- 理解ASP.NET Core - 选项(Options)
注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 Options绑定 上期我们已经聊过了配置(IConfiguration),今天我们来聊一聊O ...
- 5. abp集成asp.net core
一.前言 参照前篇<4. abp中的asp.net core模块剖析>,首先放张图,这也是asp.net core框架上MVC模块的扩展点 二.abp的mvc对象 AbpAspNetCor ...
- ASP.NET Core - 选型系统之选型配置
1. 选项 前面讲完了.NET Core 下的配置系统,我们可以通过 IConfiguration 服务从各种来源的配置中读取到配置信息,但是每次要用的时候都通过 Iconfiguration 读取配 ...
- ASP.NET Core - 选项系统之选项使用
上一篇 ASP.NET Core - 选项系统之选项配置 中提到 IOptions.IOptionsMonitor 和 IOptionsSnapshot 三个接口,通过这三个接口都可以从依赖注入容器中 ...
- ASP.NET Core - 选项系统之选项验证
就像 Web Api 接口可以对入参进行验证,避免用户传入非法的或者不符合我们预期的参数一样,选项也可以对配置源的内容进行验证,避免配置中的值与选项类中的属性不对应或者不满足预期,毕竟大部分配置都 ...
- ASP.NET Core - 选项系统之源码介绍
.NET Core 选项系统的主要实现在 Microsoft.Extensions.Options 和 Microsoft.Extensions.Options.ConfigurationExtens ...
- ASP.NET Core 源码学习之 Options[1]:Configure
配置的本质就是字符串的键值对,但是对于面向对象语言来说,能使用强类型的配置是何等的爽哉! 目录 ASP.NET Core 配置系统 强类型的 Options Configure 方法 源码解析 ASP ...
- ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor
前面我们讲到 IOptions 和 IOptionsSnapshot,他们两个最大的区别便是前者注册的是单例模式,后者注册的是 Scope 模式.而 IOptionsMonitor 则要求配置源必须是 ...
- asp.net core轻松入门之MVC中Options读取配置文件
接上一篇中讲到利用Bind方法读取配置文件 ASP.NET Core轻松入门Bind读取配置文件到C#实例 那么在这篇文章中,我将在上一篇文章的基础上,利用Options方法读取配置文件 首先注册MV ...
随机推荐
- JavaWeb 中 Filter过滤器
Filter过滤器 每博一文案 师傅说:人生无坦途,累是必须的背负,看多了,人情人暖,走遍了离合聚散,有时会 在心里对自己说,我想,我是真的累了,小时候有读不完的书,长大后有赚不尽的力. 白天在外要奋 ...
- Accurate SerDes LineRate
测试现象:(单板A板载7A series,单板B板载7K series) 1. 单板A板载2个type C接口,通过线缆自环,GTP near-end loopback, OK. 2. 2块单板A,使 ...
- 提升 Apache Hudi Upsert 性能的三个建议
Apache Hudi 社区一直在快速发展,各公司正在寻找方法来利用其强大的功能来有效地摄取和管理大规模数据集. 每周社区都会收到一些常见问题,最常见的问题与 Hudi 如何执行更新插入有关,以确保以 ...
- 如何通过Java代码将 PDF文档转为 HTML格式
虽然PDF文件适合用于打印和发布,但不适合所有类型的文档.例如,包含复杂图表和图形的文档可能无法在PDF中呈现得很好.但是HTML文件可以在任何可运行浏览器的计算机上进行阅读并显示.并且HTML还具有 ...
- 【重学C++】04 | 说透C++右值引用(上)
文章首发 [重学C++]04 | 说透C++右值引用(上) 引言 大家好,我是只讲技术干货的会玩code,今天是[重学C++]的第四讲,在前面<03 | 手撸C++智能指针实战教程>中,我 ...
- kali系统安装redis步骤
环境: 攻击机:Kali 5.16.0-kali7-amd64 192.168.13.78 靶机: Kali 5.16.0-kali7-amd64 192.168.13.94 安装 ...
- 为 Windows 系统替换优雅的苹果字体
使用 Windows 的童鞋,大家估计都用惯了默认的微软雅黑字体,字体本身也很不错,但使用久了也该换个别的字体了,换个字体换个心情嘛. 今天给大家推荐一款非常棒的一键更换 Windows 系统字体的软 ...
- 【python基础】循环语句-while循环
1.初识while循环 循环语句主要的作用是在多次处理具有相同逻辑的代码时使用.while循环是Python提供的循环语句之一. while循环的语法格式之一: 比如我们输出1-10之间的奇数,编写程 ...
- Quartz + SpringBoot 实现定时任务(多任务,多执行时间)代码模板(直接CV即可)
一,什么是Quartz quartz 是一款开源且丰富特性的Java 任务调度库,用于实现任务调度和定时任务.它支持各种任务类型和灵活的配置选项,具备作业持久化.集群和分布式调度.错误处理和重试机制等 ...
- ChatGPT教我用200行代码写一个简版Vue框架 - OpenTiny
AI 是未来最好的老师 最近,我正在准备一份关于 Vue 基础的学习材料.期间我突发奇想:能否利用现在热门的 ChatGPT 帮我创建学习内容?其实 Vue 本身不难学,特别是基础用法,但是,如果你想 ...