MarketplaceSKILL.mdLeída en 2330089
configuration
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".
Resumen
Configuration
Core Principles
- Options pattern always — Never read
IConfigurationdirectly in services. Bind configuration sections to strongly-typed classes with validation. - Validate on startup — Use
ValidateDataAnnotations()andValidateOnStart()to catch misconfiguration before the first request. - Secrets never in source — Use user secrets in development, Azure Key Vault or environment variables in production. Never commit secrets to git.
- Configuration layering —
appsettings.json→appsettings.{Environment}.json→ environment variables → user secrets. Later sources override earlier ones.
Patterns
Options Pattern
// Options class with validation attributes
public 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 validation
builder.Services.AddOptions<DatabaseOptions>()
.BindConfiguration(DatabaseOptions.SectionName)
.ValidateDataAnnotations()
.ValidateOnStart(); // Fails at startup if configuration is invalid// appsettings.json
{
"Database": {
"ConnectionString": "",
"MaxRetryCount": 3,
"CommandTimeoutSeconds": 30
}
}Injecting Options
// IOptions<T> — singleton, read once at startup, doesn't change
public 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 changes
public class BackgroundWorker(IOptionsMonitor<WorkerOptions> options)
{
public void DoWork()
{
var current = options.CurrentValue; // Always latest
}
}Custom Validation (Complex Rules)
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)
// Program.cs — add Key Vault as a configuration source
if (builder.Environment.IsProduction())
{
var keyVaultUri = new Uri(builder.Configuration["KeyVault:Uri"]!);
builder.Configuration.AddAzureKeyVault(keyVaultUri, new DefaultAzureCredential());
}Configuration for Multiple Environments
// Named options — different config per named instance
builder.Services.AddOptions<SmtpOptions>("internal")
.BindConfiguration("Smtp:Internal");
builder.Services.AddOptions<SmtpOptions>("customer")
.BindConfiguration("Smtp:Customer");
// Usage
public 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
// BAD — stringly-typed, no validation, hard to test
public class OrderService(IConfiguration config)
{
public void Process()
{
var timeout = int.Parse(config["Database:CommandTimeout"]!);
}
}
// GOOD — strongly-typed options
public class OrderService(IOptions<DatabaseOptions> options)
{
public void Process()
{
var timeout = options.Value.CommandTimeoutSeconds;
}
}Don't Put Secrets in appsettings.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
// BAD — misconfiguration discovered at runtime
builder.Services.Configure<JwtOptions>(builder.Configuration.GetSection("Jwt"));
// GOOD — fail fast at startup
builder.Services.AddOptions<JwtOptions>()
.BindConfiguration("Jwt")
.ValidateDataAnnotations()
.ValidateOnStart();Decision Guide
| Scenario | Recommendation |
|---|---|
| Binding config to class | Options pattern with BindConfiguration |
| Simple, immutable config | IOptions<T> |
| Config that changes per request | IOptionsSnapshot<T> |
| Background service watching config | IOptionsMonitor<T> |
| Development secrets | dotnet user-secrets |
| Production secrets | Azure Key Vault or environment variables |
| Validating config | ValidateDataAnnotations() + ValidateOnStart() |
| Multiple configs of same type | Named options with IOptionsSnapshot<T>.Get(name) |
Archivos 1 archivo
Instálala a mano
Deska ejecuta esto por ti, para cada agente que elijas. Para ejecutarlo tú en una terminal:
npx skills add codewithmukesh/dotnet-claude-kit --skill configurationMás de codewithmukesh
- clean-architecturecodewithmukeshClean Architecture for .NET applications. Covers the 4-project layout (Domain, Application, Infrastructure, Api), dependency inversion, use case handlers, domain entities with behavior, and infrastructure as a plugin. Load this skill when building a project with Clean Architecture, discussing layered architecture, dependency inversion, use cases, or when the architecture-advisor recommends Clean Architecture.2,200 instalaciones en skills.sh0
- architecture-advisorcodewithmukeshArchitecture selection advisor for .NET applications. Asks structured questions about domain complexity, team size, system lifetime, compliance, and integration needs, then recommends the best-fit architecture: Vertical Slice, Clean Architecture, DDD + Clean Architecture, or Modular Monolith. Load this skill when the user asks "which architecture", "choose architecture", "set up project", "new project", "architecture decision", "restructure", or "how should I organize". Always load BEFORE any architecture-specific skill.2,100 instalaciones en skills.sh0
- authenticationcodewithmukeshAuthentication and authorization for ASP.NET Core. Covers JWT bearer tokens, OpenID Connect, ASP.NET Identity, authorization policies, role and claim-based authorization, and API key authentication. Load this skill when implementing login, protecting endpoints, designing authorization rules, or when the user mentions "auth", "JWT", "bearer token", "OIDC", "OpenID Connect", "Identity", "claims", "roles", "authorize", "RequireAuthorization", "API key", or "cookie auth".2,100 instalaciones en skills.sh0
- ci-cdcodewithmukeshCI/CD pipelines for .NET applications. Covers GitHub Actions and Azure DevOps YAML pipelines with build, test, publish, and deploy stages. Load this skill when setting up continuous integration, automated testing, deployment workflows, or when the user mentions "CI/CD", "pipeline", "GitHub Actions", "Azure DevOps", "workflow", "deploy", "build pipeline", "publish", "NuGet push", "release", or "continuous integration".2,100 instalaciones en skills.sh0
- dddcodewithmukeshDomain-Driven Design tactical patterns for .NET applications. Covers aggregates, aggregate roots, value objects, domain events, domain services, strongly-typed IDs, and repository patterns for aggregate persistence. Load this skill when implementing DDD, working with aggregates, value objects, domain events, bounded contexts, or when the architecture-advisor recommends DDD + Clean Architecture. Pair with the clean-architecture skill.2,100 instalaciones en skills.sh0