Skip to main content
๐Ÿ“œ WAYPOINT LESSON

Configuration Sources and the Options Pattern

โญโญ intermediateโณ 17 min read๐Ÿ“ Lesson 123 of 265

Key-value config from multiple sources, bound into typed options objects that fail fast when wrong.

Config is data your code needs before it runs

Database locations, feature flags, limits, URLs. Rules of the road: config lives OUTSIDE compiled code, comes from SOURCES (JSON files, environment variables, command-line args โ€” most specific wins), and reaches your classes as plain injected values.

The options pattern: a typed view

Instead of string keys scattered around, bind a section to a class:

public sealed class RetryOptions
{
    public int MaxAttempts { get; set; } = 3;
    public int DelayMs { get; set; } = 200;
}

// binding (hand-rolled shape; ASP.NET's binder does the same)
var section = JsonDocument.Parse(json).RootElement.GetProperty("Retry");
var options = new RetryOptions
{
    MaxAttempts = section.GetProperty("MaxAttempts").GetInt32(),
    DelayMs = section.GetProperty("DelayMs").GetInt32(),
};

Defaults live ON the options class; config overrides them. Consumers receive RetryOptions (or IOptions<RetryOptions> in ASP.NET) โ€” never the raw config โ€” so keys are referenced in exactly one place.

Validate at startup, not at 3 a.m.

Fail FAST with a precise message:

if (options.MaxAttempts < 1)
    throw new OptionsValidationException("Retry", "MaxAttempts must be >= 1");

An invalid port number discovered at startup is a one-line fix; the same discovery on Friday night is an incident.

Environment variables: the deployment layer

Environment.GetEnvironmentVariable("CJ_RETRY__MAXATTEMPTS") โ€” deployment pipelines inject these; double-underscore is the ASP.NET convention for nesting (Retry:MaxAttempts). Env vars override file config in every mainstream host โ€” layering is the point.

Check your understanding

  • Why bind into a typed class instead of passing strings? (One place knows the keys; types catch shape errors; defaults live on the class.)
  • Which wins: file or environment? (Environment โ€” more specific deployment context.)