首页 > 编程语言 >ASP.NET Core - 选项系统之选项使用

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

时间:2023-03-23 14:11:07浏览次数:36  
标签:选项 Core ASP 读取 接口 NET

上一篇 ASP.NET Core - 选项系统之选项配置 中提到 IOptions、IOptionsMonitor 和 IOptionsSnapshot 三个接口,通过这三个接口都可以从依赖注入容器中解析出已经配置的选项类,在我们通过 Configure 方法配置选项时,这三个接口会被同时注册,但三个接口是有区别的,适用场景也有所不同。

1. IOptions

  • IOptions 对象的生命周期是 Singleton (单例),它可以在任意地方进行注入使用
  • 该接口对象在第一次使用的时候被实例化,并且选项类中的内容会一直保持不变,前面也提过选项类内容可以在配置来源修改之后更新,但是通过 IOption 解析的选项类不会随着更新而改变
  • IOptions 接口不支持命名选项模式,它是没有 get 方法的,也并不会默认读取第一个,它只能读取 String.Empty 默认命名的选项,如果没有配置默认选项的话,虽然也能解析出 Options 选项类对象,但是对象的属性都是相应类型的默认值(引用类型是 null,值类型是 0,其他的也都是相应类型的默认值)
public class OptionController : ControllerBase
{
	private readonly BlogOptions _blogOptions;
	public OptionController(IOptions<BlogOptions> options)
	{
		// 通过 IOptions<TOptions> 接口的 Value 属性读取选项类
		// 选项类始终是程序启动时加载的值,不会改变
		_blogOptions = options.Value;
	}
}

2. IOptionsMonitor

  • IOptionsMonitor 对象的生命周期是 Scoped(作用域),Scoped 生命周期的特点是不能注入到 Singleton 服务中
  • 在作用域中(最常见的一次Http请求),创建 IOptionsSnapshot 对象实例时,会从配置中读取最新选项值作为快照,并在当前作用域中始终使用该快照。也就是说一次请求中选项类内容保持不变,但是不同请求中可能因为配置来源的修改而不同
  • IOptionsMonitor 支持命名选项
public class OptionController : ControllerBase
{
	private readonly BlogOptions _blogOptions;
	public OptionController(IOptionsSnapshot<BlogOptions> optionsSnapshot)
	{
		// IOptionsSnapshot<TOptions> 可以通过 Value 属性读取默认的命名的选项类, Options 对象实例创建时读取的配置快照
		_blogOptions = optionsSnapshot.Value;
		// 也可以通过 Get 方法获取某一个命名选项,没有指定命名时,默认命名为 string.Empty
		//_blogOptions = optionsSnapshot.Get(string.Empty);
	}
}

3. IOptionsSnapshot

  • IOptionsSnapshot 对象的生命周期也是 Singleton (单例)
  • 通过 IOptionsSnapshot 接口注入的对象每次读取选项值时,都是从配置中读取最新选项值,能够实时获取配置来源的更改
  • 该接口支持命名选项模式
  • 除了可以查看 TOptions 的值,还可以监控 TOptions 配置的更改,支持重新加载配置(CurrentValue),并当配置发生更改时,进行通知(OnChange),支持缓存与缓存失效 (IOptionsMonitorCache),每次调用实例的 CurrentValue 时,会先检查缓存(IOptionsMonitorCache)是否有值,如果有值,则直接用,如果没有,则从配置中读取最新选项值,并记入缓存。当配置发生更改时,会将缓存清空。
public class OptionController : ControllerBase
{
	private readonly BlogOptions _blogOptions;
	public OptionController(IOptionsMonitor<BlogOptions> optionsMonitor)
	{
		// IOptionsMonitor<TOptions> 接口没有 Value 属性,通过 CurrentValue 获取选项类对象,
		// 每次调用 CurrentValue都会实时读取配置源,始终是最新配置的值
		_blogOptions = optionsMonitor.CurrentValue;
		// 该接口也支持通过 Get 方法获取命名选项
		_blogOptions = optionsMonitor.Get(string.Empty);
		// 可以通过 OnChange 注册事件,当配置被加载时会触发事件
		optionsMonitor.OnChange(OnOptionsChange);
	}

	[HttpGet]
	public Task<BlogOptions> Get()
	{
		return Task.FromResult(_blogOptions);
	}

	private void OnOptionsChange(BlogOptions options)
	{
		Console.WriteLine(JsonSerializer.Serialize(options));
	}
}

启动应用,调用一次 Get 接口,在 Api 控制器构造函数中注册了配置加载触发事件,之后修改 appsettings.json 配置文件中选项类对于的配置节点内容,可以看到事件触发,控制台中输出了改变之后的选项类内容。

image

4. 三个接口的选项读取机制演示

三个接口解析的选项类的差别,可以通过以下测试清楚得看出:

配置文件中初始选项节点如下:

"Blog": {
    "Title": "ASP.NET Core Options11",
    "Content": "This is a blog about Options System in ASP.NET Core Framework.",
    "CreateTime": "2022-12-06"
}

这里为了方便看出 Scoped 生命周期 IOptionSnapeshoot 接口的变化,所有通过 Web Api 接口来测试

public class OptionController : ControllerBase
{
	private readonly IOptions<BlogOptions> _blogOptions;
	private readonly IOptionsSnapshot<BlogOptions> _blogSnapshotOptions;
	private readonly IOptionsMonitor<BlogOptions> _blogMonitorOptions;
	public OptionController(
		 IOptions<BlogOptions> options,
		IOptionsSnapshot<BlogOptions> optionsSnapshot,
		IOptionsMonitor<BlogOptions> optionsMonitor
		)
	{
// 注意这里不能再把选项类对象先读取出来,否则选项类对象也不会再改变了
		_blogOptions = options;
		_blogSnapshotOptions = optionsSnapshot;
		_blogMonitorOptions = optionsMonitor;
	}

	[HttpGet]
	public Task Get()
	{
		Console.WriteLine("第一次读取配置:");
		Console.WriteLine("IOptions<TOptions>:" + JsonSerializer.Serialize(_blogOptions.Value));
		Console.WriteLine("IOptionsSnapshot<TOptions>:" + JsonSerializer.Serialize(_blogSnapshotOptions.Value));
		Console.WriteLine("IOptionsMonitor<TOptions>:" + JsonSerializer.Serialize(_blogMonitorOptions.CurrentValue));

		Console.WriteLine("请修改配置文件!");
		Console.ReadKey();

		Console.WriteLine("第二次读取配置:");
		Console.WriteLine("IOptions<TOptions>:" + JsonSerializer.Serialize(_blogOptions.Value));
		Console.WriteLine("IOptionsSnapshot<TOptions>:" + JsonSerializer.Serialize(_blogSnapshotOptions.Value));
		Console.WriteLine("IOptionsMonitor<TOptions>:" + JsonSerializer.Serialize(_blogMonitorOptions.CurrentValue));

		return Task.CompletedTask;
	}
}

之后启动应用调用 Get 接口,并在过程中将配置文件内容修改为以下:

"Blog": {
    "Title": "ASP.NET Core Options222",
    "Content": "This is a blog about Options System in ASP.NET Core Framework.",
    "CreateTime": "2022-12-06"
}

可以看到控制台的输出中,第二次读取配置的时候,IOptionsMonitor 接口读取到的内容已经改变

image

之后不要关闭应用,再调一次 Get 接口,并在过程中再次修改配置如下:

"Blog": {
    "Title": "ASP.NET Core Options333",
    "Content": "This is a blog about Options System in ASP.NET Core Framework.",
    "CreateTime": "2022-12-06"
}

这一次的 Get 请求的输出结果如下:
image

可以看到 IOptionsMonitor 接口每次都能获取到配置文件的实时值,IOptionsSnapshot 接口相较于第一次调用 Get 接口的时候已经改变,获取到了之前修改的值,但是之后的修改它又获取不到了,因为它是 Scoped 生命周期,在一次请求内是保持一致的,而 IOptions 接口获取到的选项类对象是一致不变的。



参考文章:
ASP.NET Core 中的选项模式 | Microsoft Learn
选项模式 - .NET | Microsoft Learn
面向 .NET 库创建者的选项模式指南 - .NET | Microsoft Learn
理解ASP.NET Core - 选项(Options)



ASP.NET Core 系列:

目录:ASP.NET Core 系列总结
上一篇:ASP.NET Core - 选项系统之选项配置

标签:选项,Core,ASP,读取,接口,NET
From: https://www.cnblogs.com/wewant/p/17111653.html

相关文章

  • HCIP-Datacom-Core 1.4 OSPF Stub区域与NSSA区域
    前言:HCIP-core的OSPF实验拓扑就更新完啦1.4.1实验介绍实现OSPFStub区域的配置实现OSPFNSSA区域的配置描述Type7LSA的内容描述Type7LSA与Type5LSA......
  • JasperReport 如何利用list嵌套list循环展示数据
    https://www.wanaright.com/2021/01/26/jasperreport-list-nest-list/需求描述有时候我们在做JasperReport报表的时候时常会遇到利用list循环数据的问题。这时候用......
  • ASP.NET Web API 实现 Token 验证代码
    publicclassTokenController:ApiController//定义一个名为TokenController的类,继承自ApiController类。{[HttpPost]//使用HTTPPOST请求方式。p......
  • fastadmin生成Tab选项卡
    fastadmin生成Tab选项卡2022-12-23不要看什么狗屁文档,都是骗人的,让我踩了半天坑。  关于fastadmin生成选项卡,最简单,最直接的办法就是【字段命名】,不要添加任何命......
  • 《渗透测试》WEB攻防-ASP安全&MDB下载植入&IIS短文件名&写权限&解析 2022 Day18
    1  ➢ ASP-数据库-MDB默认下载➢ ASP-数据库-ASP后门植入连接➢ ASP-中间件-IIS短文件名探针-安全漏洞➢ ASP-中间件-IIS文件上传解析-安全漏洞➢ ASP-中......
  • vue中van-picker的选项插槽使用方法
    van-picker的内部选项怎么来自定义首先要确保 VantUI 的版本在2.10.0以上然后利用插槽slot来实现,在Vant里插槽有一个进阶用法 #<van-picker:show-toolbar="fal......
  • ASP.NET Core API模型绑定和Action数据返回格式
    参考文档:https://www.cnblogs.com/FlyLolo/p/ASPNETCore2_20.html模型绑定[FromQuery]-从URL中取值。[FromRoute]-从路由中取值。[FromForm]-从表单中取值。Pos......
  • ASP.NET Core 诊断工具
    .NETCore诊断全局工具.NETCore诊断工具官方地址dotnet-countersdotnet-counters是一个性能监视工具,用于初级运行状况监视和性能调查。它通过EventCounterAPI观......
  • 关于asp.net core filters生命周期的探究
    1.背景昨天看了关于一篇api限流的文章,ASP.NETCoreWebApi接口限流,作者给出了demo,写的很好,但是我看了一遍,api限流用actionfilterattribute,觉得很奇怪,难道说每次都是用的......
  • .NET Core WebApi接口ip限流实践
    .NETCoreWebApi接口ip限流实践前言之前一直想实现接口限流,但一直没去实现,然后刚好看到一篇文章是基于AspNetCoreRateLimit组件的限流策略。这个组件不做多的介绍,想了......