
microsoft-extensions-configuration
Microsoft.Extensions.Options patterns including IValidateOptions, strongly-typed settings, validation on startup, and the Options pattern for clean configuration management.
- Installs
- 585
- Last 24h
- +8
- Trending rank
- #9636
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/aaronontheweb/dotnet-skills --skill microsoft-extensions-configuration- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads microsoft-extensions-configuration automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Microsoft.Extensions Configuration Patterns
When to Use This Skill
Use this skill when:
- Binding configuration from appsettings.json to strongly-typed classes
- Validating configuration at application startup (fail fast)
- Implementing complex validation logic for settings
- Designing configuration classes that are testable and maintainable
- Understanding IOptions<T>, IOptionsSnapshot<T>, and IOptionsMonitor<T>
Reference Files
- advanced-patterns.md: Validators with dependencies, named options, complete production example (AkkaSettings), and testing validators
Why Configuration Validation Matters
The Problem: Applications often fail at runtime due to misconfiguration - missing connection strings, invalid URLs, out-of-range values. These failures happen deep in business logic, far from where configuration is loaded.
The Solution: Validate configuration at startup. If invalid, fail immediately with a clear error message.
// BAD: Fails at runtime when someone tries to use the service
public class EmailService
{
public EmailService(IOptions<SmtpSettings> options)
{
var settings = options.Value;
// Throws NullReferenceException 10 minutes into production
_client = new SmtpClient(settings.Host, settings.Port);
}
}
// GOOD: Fails at startup with clear error
// "SmtpSettings validation failed: Host is required"
Pattern 1: Basic Options Binding
Define a Settings Class
public class SmtpSettings
{
public const string SectionName = "Smtp";
public string Host { get; set; } = string.Empty;
public int Port { get; set; } = 587;
public string? Username { get; set; }
public string? Password { get; set; }
public bool UseSsl { get; set; } = true;
}
Bind from Configuration
builder.Services.AddOptions<SmtpSettings>()
.BindConfiguration(SmtpSettings.SectionName);
// appsettings.json
{
"Smtp": {
"Host": "smtp.example.com",
"Port": 587,
"Username": "user@example.com",
"Password": "secret",
"UseSsl": true
}
}
Consume in Services
public class EmailService
{
private readonly SmtpSettings _settings;
// IOptions<T> - singleton, read once at startup
public EmailService(IOptions<SmtpSettings> options)
{
_settings = options.Value;
}
}
Pattern 2: Data Annotations Validation
For simple validation rules, use Data Annotations:
using System.ComponentModel.DataAnnotations;
public class SmtpSettings
{
public const string SectionName = "Smtp";
[Required(ErrorMessage = "SMTP host is required")]
public string Host { get; set; } = string.Empty;
[Range(1, 65535, ErrorMessage = "Port must be between 1 and 65535")]
public int Port { get; set; } = 587;
[EmailAddress(ErrorMessage = "Username must be a valid email address")]
public string? Username { get; set; }
public string? Password { get; set; }
public bool UseSsl { get; set; } = true;
}
Enable Data Annotations Validation
builder.Services.AddOptions<SmtpSettings>()
.BindConfiguration(SmtpSettings.SectionName)
.ValidateDataAnnotations() // Enable attribute-based validation
.ValidateOnStart(); // Validate immediately at startup
Key Point: .ValidateOnStart() is critical. Without it, validation only runs when the options are first accessed.
Pattern 3: IValidateOptions<T> for Complex Validation
Data Annotations work for simple rules, but complex validation requires IValidateOptions<T>:
| Scenario | Data Annotations | IValidateOptions |
|---|---|---|
| Required field | Yes | Yes |
| Range check | Yes | Yes |
| Cross-property validation | No | Yes |
| Conditional validation | No | Yes |
| External service checks | No | Yes |
| Dependency injection in validator | No | Yes |
Implementing IValidateOptions
using Microsoft.Extensions.Options;
public class SmtpSettingsValidator : IValidateOptions<SmtpSettings>
{
public ValidateOptionsResult Validate(string? name, SmtpSettings options)
{
var failures = new List<string>();
if (string.IsNullOrWhiteSpace(options.Host))
failures.Add("Host is required");
if (options.Port is < 1 or > 65535)
failures.Add($"Port {options.Port} is invalid. Must be between 1 and 65535");
// Cross-property validation
if (!string.IsNullOrEmpty(options.Username) && string.IsNullOrEmpty(options.Password))
failures.Add("Password is required when Username is specified");
// Conditional validation
if (options.UseSsl && options.Port == 25)
failures.Add("Port 25 is typically not used with SSL. Consider port 465 or 587");
return failures.Count > 0
? ValidateOptionsResult.Fail(failures)
: ValidateOptionsResult.Success;
}
}
Register the Validator
builder.Services.AddOptions<SmtpSettings>()
.BindConfiguration(SmtpSettings.SectionName)
.ValidateDataAnnotations()
.ValidateOnStart();
builder.Services.AddSingleton<IValidateOptions<SmtpSettings>, SmtpSettingsValidator>();
Order matters: Data Annotations run first, then IValidateOptions validators. All failures are collected together.
See advanced-patterns.md for validators with dependencies, named options, and a complete production example.
Pattern 4: Options Lifetime
| Interface | Lifetime | Reloads on Change | Use Case |
|---|---|---|---|
IOptions<T> | Singleton | No | Static config, read once |
IOptionsSnapshot<T> | Scoped | Yes (per request) | Web apps needing fresh config |
IOptionsMonitor<T> | Singleton | Yes (with callback) | Background services, real-time updates |
IOptionsMonitor for Background Services
public class BackgroundWorker : BackgroundService
{
private readonly IOptionsMonitor<WorkerSettings> _optionsMonitor;
private WorkerSettings _currentSettings;
public BackgroundWorker(IOptionsMonitor<WorkerSettings> optionsMonitor)
{
_optionsMonitor = optionsMonitor;
_currentSettings = optionsMonitor.CurrentValue;
_optionsMonitor.OnChange(settings =>
{
_currentSettings = settings;
});
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await DoWorkAsync();
await Task.Delay(_currentSettings.PollingInterval, stoppingToken);
}
}
}
Pattern 5: Post-Configuration
Modify options after binding but before validation:
builder.Services.AddOptions<ApiSettings>()
.BindConfiguration("Api")
.PostConfigure(options =>
{
if (!string.IsNullOrEmpty(options.BaseUrl) && !options.BaseUrl.EndsWith('/'))
options.BaseUrl += '/';
options.Timeout ??= TimeSpan.FromSeconds(30);
})
.ValidateDataAnnotations()
.ValidateOnStart();
Anti-Patterns to Avoid
1. Manual Configuration Access
// BAD: Bypasses validation, hard to test
public class MyService
{
public MyService(IConfiguration configuration)
{
var host = configuration["Smtp:Host"]; // No validation!
}
}
// GOOD: Strongly-typed, validated
public class MyService
{
public MyService(IOptions<SmtpSettings> options)
{
var host = options.Value.Host; // Validated at startup
}
}
2. Validation in Constructor
// BAD: Validation happens at runtime, not startup
public class MyService
{
public MyService(IOptions<Settings> options)
{
if (string.IsNullOrEmpty(options.Value.Required))
throw new ArgumentException("Required is missing"); // Too late!
}
}
// GOOD: Validation at startup via IValidateOptions + ValidateOnStart()
3. Forgetting ValidateOnStart
// BAD: Validation only runs when first accessed
builder.Services.AddOptions<Settings>()
.ValidateDataAnnotations(); // Missing ValidateOnStart!
// GOOD: Fails immediately if invalid
builder.Services.AddOptions<Settings>()
.ValidateDataAnnotations()
.ValidateOnStart();
4. Throwing in IValidateOptions
// BAD: Throws exception, breaks validation chain
public ValidateOptionsResult Validate(string? name, Settings options)
{
if (options.Value < 0)
throw new ArgumentException("Value cannot be negative"); // Wrong!
return ValidateOptionsResult.Success;
}
// GOOD: Return failure result
public ValidateOptionsResult Validate(string? name, Settings options)
{
if (options.Value < 0)
return ValidateOptionsResult.Fail("Value cannot be negative");
return ValidateOptionsResult.Success;
}
Summary
| Principle | Implementation |
|---|---|
| Fail fast | .ValidateOnStart() |
| Strongly-typed | Bind to POCO classes |
| Simple validation | Data Annotations |
| Complex validation | IValidateOptions<T> |
| Cross-property rules | IValidateOptions<T> |
| Environment-aware | Inject IHostEnvironment |
| Testable | Validators are plain classes |
FAQ
What does the microsoft-extensions-configuration skill do?
Microsoft.Extensions.Options patterns including IValidateOptions, strongly-typed settings, validation on startup, and the Options pattern for clean configuration management.
How do I install microsoft-extensions-configuration?
Run npx skills add https://github.com/aaronontheweb/dotnet-skills --skill microsoft-extensions-configuration in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/microsoft-extensions-configuration/ (personal) or .claude/skills/microsoft-extensions-configuration/ (project).
Which AI agents can use microsoft-extensions-configuration?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is microsoft-extensions-configuration safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains microsoft-extensions-configuration?
It is published by aaronontheweb in aaronontheweb/dotnet-skills. It has 585 recorded installs.
More from aaronontheweb/dotnet-skills
modern-csharp-coding-standards
aaronontheweb/dotnet-skills
Write modern, high-performance C code using records, pattern matching, value objects, async/await, Span /Memory , and best-practice API design patterns. Emphasizes functional-style programming with C 12+ features.
csharp-concurrency-patterns
aaronontheweb/dotnet-skills
Choosing the right concurrency abstraction in .NET - from async/await for I/O to Channels for producer/consumer to Akka.NET for stateful entity management. Avoid locks and manual synchronization unless absolutely necessary.
efcore-patterns
aaronontheweb/dotnet-skills
Entity Framework Core best practices including NoTracking by default, query splitting for navigation collections, migration management, dedicated migration services, and common pitfalls to avoid.
dependency-injection-patterns
aaronontheweb/dotnet-skills
Organize DI registrations using IServiceCollection extension methods. Group related services into composable Add methods for clean Program.cs and reusable configuration in tests.
database-performance
aaronontheweb/dotnet-skills
Database access patterns for performance. Separate read/write models, avoid N+1 queries, use AsNoTracking, apply row limits, and never do application-side joins. Works with EF Core and Dapper.
api-design
aaronontheweb/dotnet-skills
Design stable, compatible public APIs using extend-only design principles. Manage API compatibility, wire compatibility, and versioning for NuGet packages and distributed systems.
Popular backend & apis skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
entra-app-registration
microsoft/azure-skills
Guides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.
google-agents-cli-adk-code
google/agents-cli
This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent", "use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).
embedded-captions
heygen-com/hyperframes
Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet anchor rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.
entra-agent-id
microsoft/azure-skills
Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmipath, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmipath token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).
neon
neondatabase/agent-skills
Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or MCP server, and follow the branch-first workflow. Use when building an app or backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child skill neon-postgres wins for an existing DATABASEURL, SQL, schema, inspect, or search. Child skill neon-auth wins for login, users, sessions, identity routing, and Managed Better Auth setup. Child skill neon-realtime wins for live queries in reactive apps and agents. Also use for object storage, S3, buckets, serverless functions, function triggers, cron, AI gateway, LLM calls, realtime, logs, Loki, Grafana, observability, postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.