Open
Description
Description
When you use the ValidateDataAnnotations
extension method, it only works when the configuration is bound to a section of the configuration, it does not work if you want to bind the whole configuration, not a specific extension.
I expected it to work (as in an exception would be thrown) also when binding IConfiguration
instead of IConfigurationSection
.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddOptions<ApplicationOptions>()
.Bind(hostContext.Configuration)
.ValidateDataAnnotations(); // Does not work
services.AddOptions<FooOptions>()
.Bind(hostContext.Configuration.GetSection("Foo"))
.ValidateDataAnnotations(); // Does work
services.AddHostedService<Worker>();
});
}
public class Worker : BackgroundService
{
public Worker(IOptions<ApplicationOptions> options, IOptions<FoorOptions> fooOptions)
{
try
{
_ = options.Value; // Does not throw
_= fooOptions.Value; // Throws
}
catch (OptionsValidationException ex)
{
// handle exception
}
}
}
Configuration
.NET 5.0 on Windows 10.
Other information
Is having a single global "ApplicationOptions" class not an intended use case? Are we supposed to bind each configuration section individually, then have the constructor take an IOptions<>
for each configuration section?
public class Worker : BackgroundService
{
public Worker(IOptions<FooOptions> fooOptions, IOptions<BarOptions> barOptions, /* ...options */)
{
try
{
_fooOptions = fooOptions.Value;
_barOoptions = barOptions.Value;
// ...options
}
catch (OptionsValidationException ex)
{
// handle exception
}
}
}