Вы можете попробовать самостоятельно проверить класс при запуске, прежде чем добавить его в набор служб.
Запуск
var settings = Configuration.GetSection("Email").Get<EmailConfig>();
//validate
var validationResults = new List<ValidationResult>();
var validationContext = new ValidationContext(settings, serviceProvider: null, items: null);
if (!Validator.TryValidateObject(settings, validationContext, validationResults,
validateAllProperties: true)) {
//...Fail early
//will have the validation results in the list
}
services.AddSingleton(settings);
Таким образом, вы не связаны с IOptions
и вы также позволяете своему коду рано завершаться с ошибкой, и вы можете явно внедрить зависимость там, где это необходимо.
Вы можете упаковать проверку в свой собственный метод расширения, например
public static T GetValid<T>(this IConfiguration configuration) {
var obj = configuration.Get<T>();
//validate
Validator.ValidateObject(obj, new ValidationContext(obj), true);
return obj;
}
для вызововкак
EmailConfig emailSection = Configuration.GetSection("Email").GetValid<EmailConfig>();
services.AddSingleton(emailSection);
Внутренне, ValidateDataAnnotations
в основном делает то же самое.
/// <summary>
/// Validates a specific named options instance (or all when name is null).
/// </summary>
/// <param name="name">The name of the options instance being validated.</param>
/// <param name="options">The options instance.</param>
/// <returns>The <see cref="ValidateOptionsResult"/> result.</returns>
public ValidateOptionsResult Validate(string name, TOptions options)
{
// Null name is used to configure all named options.
if (Name == null || name == Name)
{
var validationResults = new List<ValidationResult>();
if (Validator.TryValidateObject(options,
new ValidationContext(options, serviceProvider: null, items: null),
validationResults,
validateAllProperties: true))
{
return ValidateOptionsResult.Success;
}
return ValidateOptionsResult.Fail(String.Join(Environment.NewLine,
validationResults.Select(r => "DataAnnotation validation failed for members " +
String.Join(", ", r.MemberNames) +
" with the error '" + r.ErrorMessage + "'.")));
}
// Ignored if not validating this instance.
return ValidateOptionsResult.Skip;
}
Исходный код