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

2020-07-01 13:00:16王冬梅

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

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; }
}

依赖注入容器

public void ConfigureServices(IServiceCollection services)
{
  services.Configure<TopItemSettings>(TopItemSettings.Month,
                    Configuration.GetSection("TopItem:Month"));
  services.Configure<TopItemSettings>(TopItemSettings.Year,
                    Configuration.GetSection("TopItem:Year"));

  services.AddRazorPages();
}

服务应用

public class TestNOModel : PageModel
{
  private readonly TopItemSettings _monthTopItem;
  private readonly TopItemSettings _yearTopItem;

  public TestNOModel(IOptionsSnapshot<TopItemSettings> namedOptionsAccessor)
  {
    _monthTopItem = namedOptionsAccessor.Get(TopItemSettings.Month);
    _yearTopItem = namedOptionsAccessor.Get(TopItemSettings.Year);
  }
}