ASP.NET Core › Dependency Injection

How does the Options pattern's IOptions<T>/IOptionsSnapshot<T> relate to and build upon the standard DI container?

Intermediate

Answer

IOptions<T>, IOptionsSnapshot<T>, and IOptionsMonitor<T> are themselves services resolved through the DI container (registered implicitly when you call Configure<T>()), demonstrating that the Options pattern is built entirely on top of standard DI infrastructure rather than being a separate mechanism -- IOptions<T> is registered as Singleton internally, IOptionsSnapshot<T> as Scoped, explaining their respective behavior around configuration change visibility and captive dependency risk.
// Configure<T> implicitly registers the necessary IOptions<T> infrastructure
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("Smtp"));

// Under the hood, this makes IOptions<SmtpSettings>, IOptionsSnapshot<SmtpSettings>,
// and IOptionsMonitor<SmtpSettings> all resolvable via the same DI container
Real-world example Understanding that IOptionsSnapshot<T> is registered as Scoped explains precisely why it can't be safely injected into a Singleton service -- it's the exact same captive dependency problem as any other Scoped service being consumed by a Singleton.

Common follow-ups: Why does IOptionsMonitor<T> avoid the captive dependency problem despite being usable in Singletons?;How would you build a custom pattern following these same DI principles?