ASP.NET Core bring cool feature like options pattern but did you feel sometimes that is difficult to trace from which
section in appsettings.json
file this options come from?
To reduce need register each options class separately and better traceability, this library does that automatically.
Install Crip.Extensions.ConfigLocator NuGet package, or GitHub package
Register all options providing assemblies where to search for classes with ConfigLocation
or ConfigValidate
attributes.
using Crip.Extensions.ConfigLocator;
builder.Services.AddConfigLocator(builder.Configuration, typeof(Program).Assembly);
Decorate options with ConfigLocation
attribute:
using Crip.Extensions.ConfigLocator;
[ConfigLocation("Path:To:Configuration:Section")]
public class MyOptions
{
public string Property { get; set; }
}
Obtain options within DI container:
public class MyController
{
public MyController(
IOptions<MyOptions> singleton,
IOptionsSnapshot<TOptions> snapshot,
IOptionsMonitor<TOptions> monitor)
{
//...
}
}
Option pattern supports multiple validation options. More about Options validation.
Define options with data annotation validation:
using Crip.Extensions.ConfigLocator;
using System.ComponentModel.DataAnnotations;
[ConfigLocation("MySection")]
[ConfigValidate]
public class MyOptions
{
[Required]
public string Foo { get; set; } = null!;
}
When MySection:Foo
is null
in appsettings.json
file, application will throw exception:
Microsoft.Extensions.Options.OptionsValidationException:
DataAnnotation validation failed for 'AttributeOptions' members: 'Foo' with the error: 'The Property field is required.'.
Define custom validator and register configuration with it:
public class MyOptionsValidator : IValidateOptions<MyOptions>
{
public ValidateOptionsResult Validate(string? name, MyOptions options)
{
if (options.Foo == "Bar")
return ValidateOptionsResult.Fail("Options 'Foo' value cannot be an 'Bar'");
return ValidateOptionsResult.Success;
}
}
[ConfigLocation("MySection")]
[ConfigValidate<MyOptionsValidator>]
// if you under C# 11 or you like to provide more than one validator:
// [ConfigValidate(typeof(MyOptionsValidator))]
public class MyOptions
{
public string Foo { get; set; } = null!;
}
When MySection:Foo
is Bar
in appsettings.json
file, application will throw exception:
Microsoft.Extensions.Options.OptionsValidationException:
Options 'Foo' value cannot be an 'Bar'
As an addition your options class may implement IValidatableObject
interface for some custom inline validation.
This package does not support named options.