上一节,我们学习了通过选项框架IOptions<>来让服务组件集成配置,同时,也学习了让服务感知配置变更的选项配置热更新框架IOptionsSnapshot、IOptionsMonitor以及对配置进行操作的PostConfigure方法。那么,本篇,我们接着来学习一下如何通过为选项数据添加验证来避免错误配置的应用接收用户流量。
一般的,我们可以通过以下三种方式来实现数据验证
- 直接注册验证函数
- 实现IValidateOptions
- 使用Microsoft.Extension.Options.DataAnnotations
下面,我们通过代码来看一下具体操作。
直接注册验证函数
服务在注册时,提供了Validate函数来让我们注册验证函数,validate函数接受2个参数,一个是bool类型的判断条件,一个是需要打印的信息。
services.AddOptions<OrderOptions>().Configure(options=> { configuration.Bind(options); }).Validate(options => { return options.MaxOrderCount <= 100; }, "MaxOrderCount不能大于100");
当然,Validate函数是一个多重载函数,可以根据实际的需要选择合适的重载方法。
实现IValidateOptions
IValidateOptions接口包含一个Validate方法,方法包括2个入参,一个stirng类型,一个需要验证的类型T,我们还使用上节的代码,首先定义一个类OrderOptionsValidate来实现IValidateOptions<OrderOptions>接口,
public class OrderOptionsValidate : IValidateOptions<OrderOptions> { public ValidateOptionsResult Validate(string name, OrderOptions options) { if (options.MaxOrderCount > 100) { return ValidateOptionsResult.Fail("MaxOrderCount 不能大于100!!!"); } else { return ValidateOptionsResult.Success; } } }
验证类实现完成后,在服务注册时,可以通过如下方式来添加该验证类。
services.AddOptions<OrderOptions>().Configure(options => { configuration.Bind(options); }).Services.AddSingleton<IValidateOptions<OrderOptions>, OrderOptionsValidate>();
Microsoft.Extension.Options.DataAnnotations
最后一种,相对比较简单,我们可以使用类似EntityFramework的DataAnnotations的属性标注形式来完成数据验证。
比如,我们在类定义时,可以使用属性标注来限制MaxOrderCount
public class OrderOptions { [Range(1,20)] public int MaxOrderCount { get; set; } = 100; public int TotalCount { get; set; } = 500; }
在服务注册时,只需要简单的ValidateDataAnnotations方法即可实现数据验证。
services.AddOptions<OrderOptions>().Configure(options => { configuration.Bind(options); }).ValidateDataAnnotations();
那么到这里,我们就学习完了选项框架数据验证的3种方式,而且选项框架部分也暂告一段落,我们来回顾一下,选项框架IOptions<>可以隔离服务和配置,是服务不必依赖于配置框架从而达到解耦;同时,选项框架提供IOptionsSnapshot、IOptionsMonitor来实现配置热更新的能力,并且,通过方法PostConfigure来实现对配置操作;最后,我们可以通过
- 直接注册验证函数
- 实现IValidateOptions
- Microsoft.Extension.Options.DataAnnotations
3种方式来实现对选项框架的数据验证。
下篇,我们将进入日志框架部分的学习,让我们一起加油。
详细代码请参阅
https://github.com/IronMarmot/Samples/tree/master/CoreSamples