本文将介绍 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的更多相关文章

  1. asp.net core选项Options模块的笔记

    这篇博客是写给自己看的.已经不止一次看到AddOptions的出现,不管是在.net core源码还是别人的框架里面,都充斥着AddOptions.于是自己大概研究了下,没有深入,因为,我的功力还是不 ...

  2. 理解ASP.NET Core - 选项(Options)

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 Options绑定 上期我们已经聊过了配置(IConfiguration),今天我们来聊一聊O ...

  3. 5. abp集成asp.net core

    一.前言 参照前篇<4. abp中的asp.net core模块剖析>,首先放张图,这也是asp.net core框架上MVC模块的扩展点 二.abp的mvc对象 AbpAspNetCor ...

  4. ASP.NET Core - 选型系统之选型配置

    1. 选项 前面讲完了.NET Core 下的配置系统,我们可以通过 IConfiguration 服务从各种来源的配置中读取到配置信息,但是每次要用的时候都通过 Iconfiguration 读取配 ...

  5. ASP.NET Core - 选项系统之选项使用

    上一篇 ASP.NET Core - 选项系统之选项配置 中提到 IOptions.IOptionsMonitor 和 IOptionsSnapshot 三个接口,通过这三个接口都可以从依赖注入容器中 ...

  6. ASP.NET Core - 选项系统之选项验证

      就像 Web Api 接口可以对入参进行验证,避免用户传入非法的或者不符合我们预期的参数一样,选项也可以对配置源的内容进行验证,避免配置中的值与选项类中的属性不对应或者不满足预期,毕竟大部分配置都 ...

  7. ASP.NET Core - 选项系统之源码介绍

    .NET Core 选项系统的主要实现在 Microsoft.Extensions.Options 和 Microsoft.Extensions.Options.ConfigurationExtens ...

  8. ASP.NET Core 源码学习之 Options[1]:Configure

    配置的本质就是字符串的键值对,但是对于面向对象语言来说,能使用强类型的配置是何等的爽哉! 目录 ASP.NET Core 配置系统 强类型的 Options Configure 方法 源码解析 ASP ...

  9. ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor

    前面我们讲到 IOptions 和 IOptionsSnapshot,他们两个最大的区别便是前者注册的是单例模式,后者注册的是 Scope 模式.而 IOptionsMonitor 则要求配置源必须是 ...

  10. asp.net core轻松入门之MVC中Options读取配置文件

    接上一篇中讲到利用Bind方法读取配置文件 ASP.NET Core轻松入门Bind读取配置文件到C#实例 那么在这篇文章中,我将在上一篇文章的基础上,利用Options方法读取配置文件 首先注册MV ...

随机推荐

  1. 通过空间占用和执行计划了解SQL Server的行存储索引

    1 索引介绍 索引是一种帮助查询语句能够快速定位到数据的一种技术.索引的存储方式有行存储索引.列存储索引和内存优化三种存储方式: 行存储索引,使用B+树结构,行存储指的是数据存储格式为堆.聚集索引和内 ...

  2. 2022-11-10:写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的频率。 为了简单起见,你可以假设: words.txt只包括小写字母和 ‘ ‘ 。 每个单词只由小写

    2022-11-10:写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的频率. 为了简单起见,你可以假设: words.txt只包括小写字母和 ' ' . 每个单词只由小写 ...

  3. 2022-07-17:1、2、3...n-1、n、n、n+1、n+2... 在这个序列中,只有一个数字有重复(n)。 这个序列是无序的,找到重复数字n。 这个序列是有序的,找到重复数字n。

    2022-07-17:1.2.3-n-1.n.n.n+1.n+2- 在这个序列中,只有一个数字有重复(n). 这个序列是无序的,找到重复数字n. 这个序列是有序的,找到重复数字n. 答案2022-07 ...

  4. 2022-03-20:给定一棵多叉树的头节点head, 每个节点的颜色只会是0、1、2、3中的一种, 任何两个节点之间的都有路径, 如果节点a和节点b的路径上,包含全部的颜色,这条路径算达标路径, (

    2022-03-20:给定一棵多叉树的头节点head, 每个节点的颜色只会是0.1.2.3中的一种, 任何两个节点之间的都有路径, 如果节点a和节点b的路径上,包含全部的颜色,这条路径算达标路径, ( ...

  5. 2021-12-22:回文子串。 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。

    2021-12-22:回文子串. 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目. 回文字符串 是正着读和倒过来读一样的字符串. 子字符串 是字符串中的由连续字符组成的一个序列. ...

  6. 各类源码下载网址(u-boot,linux,openssl,文件系统)

    一.U-Boot源代码下载 1.U-Boot的官方网站: https://www.denx.de/wiki/U-Boot/http://ftp.denx.de/pub/u-boot/ftp://ftp ...

  7. < Python全景系列-2 > Python数据类型大盘点

    <Python全景系列-2> Python数据类型大盘点 欢迎来到我们的系列博客<Python全景系列>!在这个系列中,我们将带领你从Python的基础知识开始,一步步深入到高 ...

  8. JS加载机制

    做开发多年后发现自己思维任然只定位在功能的实现:忽略了很多代码最终的实现,加载机制等 那我们接下来就借助几篇博客来理理天天看见的js:理理他究竟是怎么过执行的 一.代码检测 首先浏览器会对所有js 进 ...

  9. Spring Boot 3.1中如何整合Spring Security和Keycloak

    在今年2月14日的时候,Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器.其中包括Spring Security和Spring Boot的适配器,这意味着今后Keycloak团队 ...

  10. API NEWS | 三个Argo CD API漏洞

    欢迎大家围观小阑精心整理的API安全最新资讯,在这里你能看到最专业.最前沿的API安全技术和产业资讯,我们提供关于全球API安全资讯与信息安全深度观察. 本周,我们带来的分享如下: 关于三个Argo ...