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

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

使用 DI 服务配置选项

在配置选项时,可以通过以下两种方式通过依赖关系注入访问服务:

将配置委托传递给 OptionsBuilder 上的 Configure

services.AddOptions<MyOptions>("optionalName") .Configure<Service1, Service2, Service3, Service4, Service5>( (o, s, s2, s3, s4, s5) => o.Property = DoSomethingWith(s, s2, s3, s4, s5));

创建实现 IConfigureOptions 或 IConfigureNamedOptions 的类型,并将该类型注册为服务

建议将配置委托传递给 Configure,因为创建服务较复杂。 在调用 Configure 时,创建类型等效于框架执行的操作。 调用 Configure 会注册临时泛型 IConfigureNamedOptions,它具有接受指定的泛型服务类型的构造函数。

选项验证

appsettings.json 文件

{ "MyConfig": { "Key1": "My Key One", "Key2": 10, "Key3": 32 } }

下面的类绑定到 "MyConfig" 配置节,并应用若干 DataAnnotations 规则:

public class MyConfigOptions { public const string MyConfig = "MyConfig"; [RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$")] public string Key1 { get; set; } [Range(0, 1000, ErrorMessage = "Value for {0} must be between {1} and {2}.")] public int Key2 { get; set; } public int Key3 { get; set; } }

启用DataAnnotations验证

public void ConfigureServices(IServiceCollection services) { services.AddOptions<MyConfigOptions>() .Bind(Configuration.GetSection(MyConfigOptions.MyConfig)) .ValidateDataAnnotations(); services.AddControllersWithViews(); }

使用IValidateOptions更复杂的配置

public class MyConfigValidation : IValidateOptions<MyConfigOptions> { public MyConfigOptions _config { get; private set; } public MyConfigValidation(IConfiguration config) { _config = config.GetSection(MyConfigOptions.MyConfig) .Get<MyConfigOptions>(); } public ValidateOptionsResult Validate(string name, MyConfigOptions options) { string vor=null; var rx = new Regex(@"^[a-zA-Z''-'\s]{1,40}$"); var match = rx.Match(options.Key1); if (string.IsNullOrEmpty(match.Value)) { vor = $"{options.Key1} doesn't match RegEx \n"; } if ( options.Key2 < 0 || options.Key2 > 1000) { vor = $"{options.Key2} doesn't match Range 0 - 1000 \n"; } if (_config.Key2 != default) { if(_config.Key3 <= _config.Key2) { vor += "Key3 must be > than Key2."; } } if (vor != null) { return ValidateOptionsResult.Fail(vor); } return ValidateOptionsResult.Success; } }

IValidateOptions 允许将验证代码移出 StartUp 并将其移入类中。

使用前面的代码,使用以下代码在 Startup.ConfigureServices 中启用验证

public void ConfigureServices(IServiceCollection services) { services.Configure<MyConfigOptions>(Configuration.GetSection( MyConfigOptions.MyConfig)); services.TryAddEnumerable(ServiceDescriptor.Singleton<IValidateOptions <MyConfigOptions>, MyConfigValidation>()); services.AddControllersWithViews(); }

选项后期配置

使用 IPostConfigureOptions 设置后期配置。进行所有 IConfigureOptions 配置后运行后期配置

services.PostConfigure<MyOptions>(myOptions => { myOptions.Option1 = "post_configured_option1_value"; });

使用 PostConfigureAll 对所有配置实例进行后期配置

在启动期间访问选项

IOptions 和 IOptionsMonitor 可用于 Startup.Configure 中,因为在 Configure 方法执行之前已生成服务。

public void Configure(IApplicationBuilder app, IOptionsMonitor<MyOptions> optionsAccessor) { var option1 = optionsAccessor.CurrentValue.Option1; }

结论

IOptions<>是单例,因此一旦生成了,除非通过代码的方式更改,它的值是不会更新的。

IOptionsMonitor<>也是单例,但是它通过IOptionsChangeTokenSource<> 能够和配置文件一起更新,也能通过代码的方式更改值。

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

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