.NET Core / Web API71 min total · 19 parts
Building REST APIs with ASP.NET Core: Routing, Middleware, and Dependency Injection
Part 10 of 19 · ~1 min
Configuration and the Options Pattern
Bench sends a reminder email an hour before a reservation starts, and the settings for that arrive in stacked layers — appsettings.json first, then a appsettings.Production.json specific to whatever environment is actually running, then anything set directly in the environment, then whatever's passed on the command line — where each layer is free to override whatever the one underneath it said:
{
"ReminderSettings": {
"SendGridFromAddress": "bench@ridgeline.edu",
"MinutesBeforeStart": 60
}
}
Binding that section to a real class — the options pattern — beats scattering builder.Configuration["ReminderSettings:MinutesBeforeStart"] string lookups across the codebase:
public class ReminderSettings
{
public string SendGridFromAddress { get; set; } = "";
public int MinutesBeforeStart { get; set; }
}
builder.Services.Configure<ReminderSettings>(builder.Configuration.GetSection("ReminderSettings"));
class ReminderSender
{
private readonly ReminderSettings _settings;
public ReminderSender(IOptions<ReminderSettings> options) => _settings = options.Value;
}
There's a real difference in when each of these actually looks at configuration. IOptions<T> is a singleton, and it reads configuration a single time, at startup — whatever it captured then is what every consumer gets for the rest of the process's life. IOptionsSnapshot<T> is scoped instead, so it goes back and re-reads configuration fresh on every request, which only actually buys you anything once something can change that configuration without a full redeploy — a JSON file with reload-on-change turned on, say. Bench's own SendGrid API key never touches either one as a literal string typed into appsettings.json — it lives in user secrets on Dana's laptop and an environment variable in production, the same rule that applies to any connection string or key: source control is simply not where a secret belongs.