Validate Configuration Options with ASP.NET Core
Configuring an ASP.NET Core application can be done in a variety of ways, including using command-line arguments, environment variables, and JSON files. One way to ensure that the options you have configured for your application are valid is to use the IOptions
Option validation is the process of verifying that the options used in an application have the correct values. This is important because options can be used to control various aspects of an application's behavior, such as its performance, security, and functionality. If an option has an incorrect value, it can cause the application to behave unexpectedly or even fail.
First, you need to define a class that will represent your configuration options. This class should have properties for each of the options you want to be able to set. For example:
public class MyConfig
{
public string Option1 { get; set; }
public int Option2 { get; set; }
public bool IsOption3 { get; set; }
}
Next, you need to register your configuration options with the Dependency Injection (DI) container. This is done in the ConfigureServices method of your Startup class, like so:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
}
Here, Configuration is an IConfiguration object that is provided by the Startup class and contains the application's configuration settings. The GetSection method is used to retrieve the section of the configuration that contains the options for MyConfig.
Once your configuration options have been registered with the DI container, you can inject an IOptions<MyConfig>
object into any of your application's services. This object will contain the options that have been configured for MyConfig.
public class MyService
{
private readonly MyConfig _config;
public MyService(IOptions<MyConfig> options)
{
_config = options.Value;
}
}
You can then access the individual options of MyConfig through the Value property of the IOptions<MyConfig>
object.
Using attributes
Validating your configuration options is a simple matter of adding [Required] and/or [Range] attributes to the properties of your MyConfig class. For example:
public class MyConfig
{
[Required]
public string Option1 { get; set; }
[Range(1, 10)]
public int Option2 { get; set; }
public bool Option3 { get; set; } = true;
}
These attributes will cause an exception to be thrown if the corresponding options are not provided, or if they are provided but do not satisfy the specified requirements.
You can use all attributes of the System.ComponentModel.DataAnnotations namespace.
Using PostConfigure
Another way is using the PostConfigure method to perform additional validation and/or initialization. This method takes a generic type parameter that specifies the type of options being configured, and a lambda expression that receives those options as a parameter. For example:
services.PostConfigure<MyConfig>(config =>
{
if (string.IsNullOrEmpty(config.Option1))
{
throw new ArgumentException(
$"{nameof(MyConfig.Option1)} of {nameof(MyConfig)} must be specified.");
}
if (config.Option2 <= 0)
{
config.Option2 = 1;
}
});
The advantage here is that even complex validation scenarios are covered and defaults can also be implemented more easily.
Likewise, custom execution types can be thrown at this point, which can be given their own section in Application Insights, for example, in order to design evaluations more easily.
In summary, using the IOptions