CodeOath
← All posts
.NET Core / Web API70 min total · 19 parts

Building REST APIs with ASP.NET Core: Routing, Middleware, and Dependency Injection

Contents — Part 10 of 19: Configuration and the Options Pattern
Part 10 of 19 · ~1 min

Configuration and the Options Pattern

Configuration in ASP.NET Core is layered — appsettings.json, an environment-specific appsettings.{Environment}.json, environment variables, and command-line arguments are merged together, with later sources overriding earlier ones:

{
  "SmtpSettings": {
    "Host": "smtp.example.com",
    "Port": 587
  }
}

Binding a settings section to a strongly-typed class (the options pattern) is preferred over reading raw configuration strings by key scattered across the codebase:

public class SmtpSettings
{
    public string Host { get; set; } = "";
    public int Port { get; set; }
}

builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("SmtpSettings"));

// Injected wherever needed, via IOptions<T> (or IOptionsSnapshot<T> for Scoped/config-reload scenarios)
class EmailSender
{
    private readonly SmtpSettings _settings;
    public EmailSender(IOptions<SmtpSettings> options) => _settings = options.Value;
}

IOptions<T> is registered as a singleton and reads configuration once at startup; IOptionsSnapshot<T> is scoped and re-reads configuration per request, useful when configuration can change (e.g. via a reloadable JSON file) without restarting the app. Secrets (connection strings, API keys) belong in user secrets locally and a real secret store (environment variables, Azure Key Vault, AWS Secrets Manager) in production — never committed into appsettings.json in source control.