Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
I've got a scenario where I'm using OptionsBuilderExtensions.ValidateOnStart
to validate some settings to fail fast if there are any values missing etc.
I've wired in an IValidateOptions<>
implementation to do the validation, and I have an IConfigureOptions<>
implementation to change some of the settings on load.
The issue I'm experiencing is both the configure and validate implementations get called twice, and if I change any of the setting values in the first call to configure, it resets on the second call.
Here is a cutdown sample that illustrates my point:
Simple program.cs
setup:
using Microsoft.Extensions.Options;
using OptionsValidationExample;
var builder = WebApplication.CreateBuilder(args);
builder
.Services
.AddOptions<GreetingSettings>()
.Configure(settings => settings.Name = "Initial Name")
.ValidateOnStart();
builder.Services.AddSingleton<IValidateOptions<GreetingSettings>, SettingsValidateOptions>();
builder.Services.AddSingleton<IConfigureOptions<GreetingSettings>, SettingsConfigureOptions>();
var app = builder.Build();
app.MapGet("/", (IOptions<GreetingSettings> settings) =>
{
return $"Hello {settings.Value.Name}!";
});
app.Run();
And my GreetingSettings.cs file complete with validateoptions and configureoptions implementations:
using Microsoft.Extensions.Options;
using System.Diagnostics;
namespace OptionsValidationExample;
public class GreetingSettings
{
public string Name { get; set; } = null!;
}
public class SettingsConfigureOptions : IConfigureOptions<GreetingSettings>
{
public void Configure(GreetingSettings options)
{
// This method gets called twice due to ValidateOnStartup for the settings.
Debugger.Break();
// The second time it should come through as "Changed Name".
Debug.Assert(options.Name == "Initial Name");
options.Name = "Changed Name";
}
}
public class SettingsValidateOptions : IValidateOptions<GreetingSettings>
{
public ValidateOptionsResult Validate(string name, GreetingSettings options)
{
// This method gets called twice: once for ValidateOnStartup and once for first usage.
Debugger.Break();
return ValidateOptionsResult.Success;
}
}
Any suggestions on how to fix this?
Many thanks in advance,
Mark.
Expected Behavior
I would have thought the validate would run once on startup, and further calls to any injected IOptions<>.value would not result in another validation.
Also, the fact that my IConfigureOptions implementation gets run on startup led me to expect the configure would not get called again after startup.
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version
net6.0
Anything else?
No response