Configuration

codewithmukesh/dotnet-claude-kit/skills/configuration

by codewithmukesh23300897f4d1No license754 starsListed Oct 8, 2026Updated Oct 8, 2026Repository updated 2 months ago

Configuration patterns for .NET 10 applications. Covers the Options pattern, IOptionsSnapshot vs IOptions, secrets management, and environment-based configuration. Load this skill when setting up application configuration, managing secrets, binding configuration sections, or when the user mentions "configuration", "appsettings", "Options pattern", "IOptions", "IOptionsSnapshot", "secrets", "user secrets", "environment variables", "connection string", or "config binding".

Instructions only

Configuration

Core Principles

  1. Options pattern always — Never read IConfiguration directly in services. Bind configuration sections to strongly-typed classes with validation.
  2. Validate on startup — Use ValidateDataAnnotations() and ValidateOnStart() to catch misconfiguration before the first request.
  3. Secrets never in source — Use user secrets in development, Azure Key Vault or environment variables in production. Never commit secrets to git.
  4. Configuration layering — appsettings.json → appsettings.{Environment}.json → environment variables → user secrets. Later sources override earlier ones.

Patterns

Options Pattern

csharp
// Options class with validation attributespublic class DatabaseOptions{    public const string SectionName = "Database";
    [Required]    public required string ConnectionString { get; init; }
    [Range(1, 100)]    public int MaxRetryCount { get; init; } = 3;
    [Range(1, 60)]    public int CommandTimeoutSeconds { get; init; } = 30;}
// Registration with validationbuilder.Services.AddOptions<DatabaseOptions>()    .BindConfiguration(DatabaseOptions.SectionName)    .ValidateDataAnnotations()    .ValidateOnStart(); // Fails at startup if configuration is invalid
json
// appsettings.json{  "Database": {    "ConnectionString": "",    "MaxRetryCount": 3,    "CommandTimeoutSeconds": 30  }}

Injecting Options

csharp
// IOptions<T> — singleton, read once at startup, doesn't changepublic class OrderService(IOptions<DatabaseOptions> options){    private readonly DatabaseOptions _db = options.Value;}
// IOptionsSnapshot<T> — scoped, re-reads per request (for reloadable config)public class OrderService(IOptionsSnapshot<DatabaseOptions> options){    private readonly DatabaseOptions _db = options.Value;}
// IOptionsMonitor<T> — singleton, actively watches for changespublic class BackgroundWorker(IOptionsMonitor<WorkerOptions> options){    public void DoWork()    {        var current = options.CurrentValue; // Always latest    }}

Custom Validation (Complex Rules)

csharp
builder.Services.AddOptions<JwtOptions>()    .BindConfiguration("Jwt")    .Validate(options =>    {        if (string.IsNullOrEmpty(options.Key) || options.Key.Length < 32)            return false;        if (options.ExpirationMinutes <= 0)            return false;        return true;    }, "JWT key must be at least 32 characters and expiration must be positive")    .ValidateOnStart();

Azure Key Vault (Production)

csharp
// Program.cs — add Key Vault as a configuration sourceif (builder.Environment.IsProduction()){    var keyVaultUri = new Uri(builder.Configuration["KeyVault:Uri"]!);    builder.Configuration.AddAzureKeyVault(keyVaultUri, new DefaultAzureCredential());}

Configuration for Multiple Environments

csharp
// Named options — different config per named instancebuilder.Services.AddOptions<SmtpOptions>("internal")    .BindConfiguration("Smtp:Internal");builder.Services.AddOptions<SmtpOptions>("customer")    .BindConfiguration("Smtp:Customer");
// Usagepublic class EmailService(IOptionsSnapshot<SmtpOptions> options){    public async Task SendInternalEmail(string to, string body)    {        var smtp = options.Get("internal");        // ...    }}

Anti-patterns

Don't Read IConfiguration Directly

csharp
// BAD — stringly-typed, no validation, hard to testpublic class OrderService(IConfiguration config){    public void Process()    {        var timeout = int.Parse(config["Database:CommandTimeout"]!);    }}
// GOOD — strongly-typed optionspublic class OrderService(IOptions<DatabaseOptions> options){    public void Process()    {        var timeout = options.Value.CommandTimeoutSeconds;    }}

Don't Put Secrets in appsettings.json

json
// BAD — committed to source control{  "Jwt": { "Key": "super-secret-key" },  "Database": { "ConnectionString": "Server=prod;Password=secret" }}
// GOOD — appsettings.json has defaults/structure only{  "Jwt": { "Key": "", "Issuer": "myapp", "Audience": "myapp" },  "Database": { "ConnectionString": "" }}// Secrets provided via user-secrets (dev) or env vars / Key Vault (prod)

Don't Skip Startup Validation

csharp
// BAD — misconfiguration discovered at runtimebuilder.Services.Configure<JwtOptions>(builder.Configuration.GetSection("Jwt"));
// GOOD — fail fast at startupbuilder.Services.AddOptions<JwtOptions>()    .BindConfiguration("Jwt")    .ValidateDataAnnotations()    .ValidateOnStart();

Decision Guide

ScenarioRecommendation
Binding config to classOptions pattern with BindConfiguration
Simple, immutable configIOptions<T>
Config that changes per requestIOptionsSnapshot<T>
Background service watching configIOptionsMonitor<T>
Development secretsdotnet user-secrets
Production secretsAzure Key Vault or environment variables
Validating configValidateDataAnnotations() + ValidateOnStart()
Multiple configs of same typeNamed options with IOptionsSnapshot<T>.Get(name)

Source and attribution

Source:codewithmukesh/dotnet-claude-kitinskills/configurationat commit2330089

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal

More from codewithmukesh/dotnet-claude-kit

Wrap Up

codewithmukesh

Captures end-of-session work, pending tasks and learnings into a handoff file, and reloads it at session start.

Productivity & Workflow754updated 2 months ago

Workflow Mastery

codewithmukesh

Claude Code workflow mastery for .NET developers. Covers parallel execution with git worktrees, plan mode strategy, verification loops, auto-formatting hooks, permission setup for dotnet CLI, prompting techniques, subagent patterns, and context discipline — token budget management, MCP-first navigation, lazy loading, and subagent isolation — all adapted for the .NET ecosystem. Load this skill when setting up Claude Code for a .NET project, optimizing workflows, running parallel sessions, when context is running low or sessions feel sluggish, when exploring a large codebase efficiently, or when the user mentions "productivity", "workflow", "parallel", "worktree", "plan mode", "permissions", "hooks", "10x", "setup Claude Code", "speed up development", "context", "tokens", "budget", "running out of context", "too many files", or "large codebase". Inspired by tips from Boris Cherny (creator of Claude Code) and the Anthropic team.

Awaiting classification754updated 2 months ago

Vertical Slice

codewithmukesh

Guides .NET developers in structuring applications with Vertical Slice Architecture, covering feature folders, endpoint grouping and handler patterns.

Software Development754updated 2 months ago

Testing

codewithmukesh

Testing strategy for .NET 10 applications. Covers xUnit v3, WebApplicationFactory for integration tests, Testcontainers for real database testing, Verify for snapshot testing, and the AAA pattern. Load this skill when writing tests, setting up test infrastructure, reviewing test coverage, or when the user mentions "test", "xUnit", "WebApplicationFactory", "Testcontainers", "integration test", "unit test", "bUnit", "snapshot test", "Verify", "test coverage", "AAA pattern", "WireMock", or "FakeTimeProvider".

Awaiting classification754updated 2 months ago

Tdd

codewithmukesh

Guided test-driven development workflow for .NET 10 using xUnit v3, WebApplicationFactory, Testcontainers, and Verify snapshots. Follows the strict red-green-refactor cycle. Use when: "TDD", "test-driven", "let's TDD this", "red green refactor", "write the test first", or when building a feature with clear acceptance criteria.

Awaiting classification754updated 2 months ago

Spec

codewithmukesh

Turns a vague feature idea into an agreed, persisted specification file through structured questioning rounds.

Productivity & Workflow754updated 2 months ago