Chapter 2 · Practice 2 of 4
Bind settings into options classes and validate them on start
Why it matters
Reading IConfiguration["Payments:ApiKey"] in services spreads magic strings everywhere and fails only when that line runs. The options pattern binds a configuration section to a class and injects it as IOptions<T>.
Add validation and run it at startup:
ValidateDataAnnotations()applies[Required],[Range]and similar attributes.Validate(...)adds rules that span properties.ValidateOnStart()(orAddOptionsWithValidateOnStart) makes a bad value stop the app at boot, not on the first request.
Pick the interface by need: IOptions<T> is a singleton read once; IOptionsSnapshot<T> is scoped and re-reads per request; IOptionsMonitor<T> is a singleton with change notifications.
Example
public sealed class PaymentOptions
{
[Required, Url] public required string BaseUrl { get; init; }
[Required] public required string ApiKey { get; init; }
[Range(1, 60)] public int TimeoutSeconds { get; init; } = 10;
}
builder.Services.AddOptionsWithValidateOnStart<PaymentOptions>()
.BindConfiguration("Payments")
.ValidateDataAnnotations();