-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Options: Validate named registrations #45671
Comments
Tagging subscribers to this area: @maryamariyan Issue DetailsBackground and MotivationCurrently the Options API will return a new instance of the options class even if it was not configured. This is especially problematic with named options, where a misconfiguration can easily occur. This is compounded by the fact that validation is configured per named instance. I suggest a way to validate that a named option has been explicitly registered. Proposed APInamespace Microsoft.Extensions.Options
{
public class OptionsBuilder<T> {
+ ValidateNames();
}
} Usage Examplesvar services = new ServiceCollection();
services.AddOptions<MyOptions>().ValidateNames();
services.AddOptions<MyOptions>("X").Configure(o => { ... });
var serviceProvider = services.BuildServiceProvider();
var myOptions = serviceProvider.GetService<IOptionsMonitor<MyOptions>>();
myOptions.Get("X") // returns value
myOptions.Get("Y") // throws --> Alternative DesignsAnother option is to allow validations to be defined for all instances. Currently there's a services.AddAllOptions<MyOptions>().ValidateDataAnnotations(); RisksNone - this behavior does not change existing options as it must be opted into.
|
We added a new feature into .NET 6 Preview 2 for allowing options validation also for named options. For more information check out this original issue: #36391 Closing as fixed. |
@maryamariyan I took a quick look at the PR and I don't think this use case is covered. It's not about validating the options at start-up, it's validating that only pre-registered names can be used when calling An unconfigured named option is very hard to debug without this. |
We would need to add another API for that. This one can't cover arbitrary names |
@maryamariyan Could you please reopen the issue? |
How would this work if all names aren't known up front? |
In our use case all names are registered to the DI engine. I experimented a bit, and it turns out the following works for validating all named options (the alternate design I suggested): services.AddSingleton<IValidateOptions<MyOptions>>(new ValidateOptions<MyOptions>(null, o => Validate(o), "invalid"));
services.AddSingleton<IValidateOptions<MyOptions>>(new DataAnnotationValidateOptions<MyOptions>(null)) But the API is not easily discoverable (passing |
I'm not sure I'm following... What works. Can you describe the end to end here? |
The problem we had was that an unexpected name was used, which retrieved an unconfigured and unvalidated instance of an option. I suggested 2 solutions (not mutually exclusive):
The latter is possible with the above code sample. |
And this has nothing to do with validation on startup right? |
Right. Validating this at start-up could be an added bonus. |
Got it, this only works when you specify which names up front. |
Background and Motivation
Currently the Options API will return a new instance of the options class even if it was not configured. This is especially problematic with named options, where a misconfiguration can easily occur. This is compounded by the fact that validation is configured per named instance. I suggest a way to validate that a named option has been explicitly registered.
Proposed API
namespace Microsoft.Extensions.Options { public class OptionsBuilder<T> { + ValidateNames(); } }
Usage Examples
Alternative Designs
Another option is to allow validations to be defined for all instances. Currently there's a
ConfigureAll
method that allows defining an action that would run on all named options, but no API to configure validation for all instances. So we could have something likeAddAllOptions
(not the best name, I know):Risks
None - this behavior does not change existing options as it must be opted into.
The text was updated successfully, but these errors were encountered: