如何使用.NET Core 选项模式【Options】

ASP.NET Core引入了Options模式,使用类来表示相关的设置组。简单的来说,就是用强类型的类来表达配置项,这带来了很多好处。利用了系统的依赖注入,并且还可以利用配置系统。它使我们可以采用依赖注入的方法直接使用绑定的一个POCO对象,这个POCO对象就叫做Options对象。也可以叫做配置对象。

以下大多内容来自官方文档,我只是个翻译官或者叫搬运工吧!

引入Options扩展包

PM>Package-install Microsoft.Extensions.Options

绑定分层配置

在appsetting.json文件增加如下配置

"Position": { "Title": "Editor", "Name": "Joe Smith" }

创建以下 PositionOptions 类:

public class PositionOptions { public const string Position = "Position"; public string Title { get; set; } public string Name { get; set; } }

选项类:

必须是包含公共无参数构造函数的非抽象类。

类型的所有公共读写属性都已绑定。

不会绑定字段。 在上面的代码中,Position 未绑定。 由于使用了 Position 属性,因此在将类绑定到配置提供程序时,不需要在应用中对字符串 "Position" 进行硬编码。

类绑定

调用 ConfigurationBinder.Bind 将 PositionOptions 类绑定到 Position 部分。然后就可以用了,当然这种方式在开发.NET Core种并不常用,一般采用依赖注入的方式注入。

var positionOptions = new PositionOptions(); Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

使用 ConfigurationBinder.Get 可能比使用 ConfigurationBinder.Bind 更方便。

positionOptions = Configuration.GetSection(PositionOptions.Position).Get<PositionOptions>();

依赖项注入服务容器

修改ConfigureServices方法

public void ConfigureServices(IServiceCollection services) { services.Configure<PositionOptions>(Configuration.GetSection( PositionOptions.Position)); services.AddRazorPages(); }

通过使用前面的代码,以下代码将读取位置选项:

public class Test2Model : PageModel { private readonly PositionOptions _options; public Test2Model(IOptions<PositionOptions> options) { _options = options.Value; } public ContentResult OnGet() { return Content($"Title: {_options.Title} \n" + $"Name: {_options.Name}"); } }

选项接口
初学者会发现这个框架有3个主要的面向消费者的接口:IOptions、IOptionsMonitor以及IOptionsSnapshot。

这三个接口初看起来很类似,所以很容易引起困惑,什么场景下该用哪个接口呢?

1.IOptions

不支持

(1)在应用启动后读取配置数据。

(2)命名选项

注册为单一实例,可以注入到任何服务生存期。

2.IOptionsSnapshot

作用域容器配置热更新使用它

注册为范围内,因此无法注入到单一实例服务

支持命名选项

3.IOptionsMonitor

用于检索选项并管理 TOptions 实例的选项通知。

注册为单一实例且可以注入到任何服务生存期。

支持

(1)更改通知
(2)命名选项
(3)可重载配置
(4)选择性选项失效

使用 IOptionsSnapshot 读取已更新的数据

IOptionsMonitor 和 IOptionsSnapshot 之间的区别在于:

IOptionsMonitor 是一种单一示例服务,可随时检索当前选项值,这在单一实例依赖项中尤其有用。

IOptionsSnapshot 是一种作用域服务,并在构造 IOptionsSnapshot 对象时提供选项的快照。 选项快照旨在用于暂时性和有作用域的依赖项。

public class TestSnapModel : PageModel { private readonly MyOptions _snapshotOptions; public TestSnapModel(IOptionsSnapshot<MyOptions> snapshotOptionsAccessor) { _snapshotOptions = snapshotOptionsAccessor.Value; } public ContentResult OnGet() { return Content($"Option1: {_snapshotOptions.Option1} \n" + $"Option2: {_snapshotOptions.Option2}"); } }

IOptionsMonitor

public class TestMonitorModel : PageModel { private readonly IOptionsMonitor<MyOptions> _optionsDelegate; public TestMonitorModel(IOptionsMonitor<MyOptions> optionsDelegate ) { _optionsDelegate = optionsDelegate; } public ContentResult OnGet() { return Content($"Option1: {_optionsDelegate.CurrentValue.Option1} \n" + $"Option2: {_optionsDelegate.CurrentValue.Option2}"); } }

命名选项支持使用 IConfigureNamedOptions

命名选项:

当多个配置节绑定到同一属性时有用。

区分大小写。

appsettings.json文件

{ "TopItem": { "Month": { "Name": "Green Widget", "Model": "GW46" }, "Year": { "Name": "Orange Gadget", "Model": "OG35" } } }

下面的类用于每个节,而不是创建两个类来绑定 TopItem:Month 和 TopItem:Year

public class TopItemSettings { public const string Month = "Month"; public const string Year = "Year"; public string Name { get; set; } public string Model { get; set; } }

依赖注入容器

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/30f8dbfae830dc09386657efa4575a60.html