Skip to main content Skills Marketplace Descubra e explore skills de IA criadas pela comunidade.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Copiar promptMostrar detalhes do prompt Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
npx skills add https://github.com/rudironsoni/Synaxis --skill dotnet-csharp-configurationO comando permanece em uma só linha. Role horizontalmente para revisá-lo antes de copiar.
Prefere uma cópia local? Baixe os arquivos disponíveis atualmente no SkillsMP.
Baixar Zip Baixando... Ocupações relacionadas SOC
Baseado na classificação ocupacional SOC
name dotnet-csharp-configuration category fundamentals subcategory di-and-services description Configures Options pattern, user secrets, and feature flags. IOptions<T>, FeatureManagement. license MIT targets ["*"] tags ["csharp","dotnet","skill"] version 0.0.1 author dotnet-agent-harness invocable true claudecode {"allowed-tools":["Read","Grep","Glob","Bash","Write","Edit"]} codexcli {"short-description":".NET skill guidance for csharp tasks"} opencode {"allowed-tools":["Read","Grep","Glob","Bash","Write","Edit"]} copilot {} geminicli {} antigravity {}
dotnet-csharp-configuration
Configuration patterns for .NET applications using Microsoft.Extensions.Configuration and Microsoft.Extensions.Options.
Covers the Options pattern (IOptions<T>, IOptionsMonitor<T>, IOptionsSnapshot<T>), validation, user secrets,
environment-based configuration, and feature flags with Microsoft.FeatureManagement.
Scope
Options pattern (IOptions, IOptionsMonitor, IOptionsSnapshot)
Options validation and ValidateOnStart
User secrets and environment-based configuration
Feature flags with Microsoft.FeatureManagement
Configuration source precedence
Out of scope
DI container mechanics and service lifetimes -- see [skill:dotnet-csharp-dependency-injection]
EditorConfig and analyzer rule configuration -- see [skill:dotnet-editorconfig]
Structured logging pipeline configuration -- see [skill:dotnet-structured-logging]
Cross-references: [skill:dotnet-csharp-dependency-injection] for service registration patterns,
[skill:dotnet-csharp-coding-standards] for naming conventions.
Configuration Sources and Precedence
Default configuration sources in WebApplication.CreateBuilder (last wins):
appsettings.json
appsettings.{Environment}.json
User secrets (Development only)
Environment variables
Command-line arguments
var builder = WebApplication.CreateBuilder(args );
builder.Configuration.AddJsonFile("features.json" , optional: true , reloadOnChange: true );
```csharp
---
## Options Pattern
Bind configuration sections to strongly typed classes and inject them via DI.
### Defining Options Classes
```csharp
public sealed class SmtpOptions
{
public const string SectionName = ;
Host { ; ; } = ;
Port { ; ; } = ;
FromAddress { ; ; } = ;
UseSsl { ; ; } = ;
}
```text
> Options classes use `{ ; ; }` ( ` `) because the configuration binder `PostConfigure` need to mutate
> properties. Use `[Required]` via data annotations mandatory fields instead.
```csharp
builder.Services
.AddOptions<SmtpOptions>()
.BindConfiguration(SmtpOptions.SectionName)
.ValidateDataAnnotations()
.ValidateOnStart();
```text
```json
{
: {
: ,
: ,
: ,
:
}
}
```text
---
| Interface | Lifetime | Reload Behavior | Use Case |
| --------------------- | --------- | --------------------------------- | ------------------------------- |
| `IOptions<T>` | Singleton | Never reloads after startup | Static config, most services |
| `IOptionsSnapshot<T>` | Scoped | Reloads per request/scope | Per-request config ASP.NET |
| `IOptionsMonitor<T>` | Singleton | Live reload + change notification | Singletons, background services |
```csharp
{
SmtpOptions _smtp = options.Value;
{
Task.CompletedTask;
}
}
{
=> monitor.CurrentValue.EnabledFeatures.Contains(feature);
}
{
=> snapshot.Value.MarkupPercent;
}
```text
```csharp
:
{
IDisposable? _changeListener;
CacheOptions _current;
{
_current = monitor.CurrentValue;
_changeListener = monitor.OnChange(updated =>
{
_current = updated;
});
}
=> _changeListener?.Dispose();
}
```text
---
```csharp
System.ComponentModel.DataAnnotations;
{
SectionName = ;
[ ]
Host { ; ; } = ;
[ ]
Port { ; ; } = ;
[ ]
FromAddress { ; ; } = ;
}
builder.Services
.AddOptions<SmtpOptions>()
.BindConfiguration(SmtpOptions.SectionName)
.ValidateDataAnnotations()
.ValidateOnStart();
```text
Use validation logic requires cross-property checks external dependencies.
```csharp
: < >
{
{
failures = List< >();
(options.UseSsl && options.Port == )
{
failures.Add( );
}
( .IsNullOrWhiteSpace(options.Host))
{
failures.Add( );
}
failures.Count >
? ValidateOptionsResult.Fail(failures)
: ValidateOptionsResult.Success;
}
}
builder.Services.AddSingleton<IValidateOptions<SmtpOptions>, SmtpOptionsValidator>();
```text
Always use `.ValidateOnStart()` to surface configuration errors at startup instead of at first resolution. Without it,
invalid config only throws `IOptions<T>.Value` first accessed.
---
Store sensitive values outside source control during development.
```bash
dotnet user-secrets
dotnet user-secrets
dotnet user-secrets
dotnet user-secrets list
dotnet user-secrets clear
```text
User secrets are stored `~/.microsoft/usersecrets/<UserSecretsId>/secrets.json` `appsettings.json`
values Development.
**Key rules:**
- Never use user secrets production -- use environment variables, Azure Key Vault, other vault providers
- User secrets are loaded automatically `ASPNETCORE_ENVIRONMENT=Development`
- For non-web hosts, explicitly : `builder.Configuration.AddUserSecrets<Program>()`
---
```csharp
```csharp
```text
appsettings.json
appsettings.Development.json
appsettings.Staging.json
appsettings.Production.json
```json
```csharp
env = builder.Environment.EnvironmentName;
```csharp
```
{
builder.Services.AddSingleton<IEmailSender, ConsoleEmailSender>();
}
{
builder.Services.AddSingleton<IEmailSender, SmtpEmailSender>();
}
```text
---
`Microsoft.FeatureManagement.AspNetCore` provides structured feature flag support filters, targeting, gradual
rollout.
```bash
dotnet package Microsoft.FeatureManagement.AspNetCore
```bash
```csharp
builder.Services.AddFeatureManagement();
```csharp
```json
{
: {
: ,
: {
: [
{
: ,
: { : }
}
]
},
: {
: [
{
: ,
: {
: {
: [ ],
: [{ : , : }],
:
}
}
}
]
}
}
}
```text
```csharp
{
[ ]
{
( featureManager.IsEnabledAsync( ))
{
Ok( { version = , dashboard = });
}
Ok( { version = , dashboard = });
}
}
```text
```csharp
[ ]
[ ]
{
results = _searchService.SearchAsync(query, ct);
Ok(results);
}
```text
| Filter | Purpose |
| ------------ | -------------------------------------------------------- |
| `Percentage` | Enable N%
{
{
userAgent = accessor.HttpContext?.Request.Headers.UserAgent.ToString() ?? ;
settings = context.Parameters.Get<BrowserFilterSettings>();
Task.FromResult(
settings?.AllowedBrowsers?.Any(b =>
userAgent.Contains(b, StringComparison.OrdinalIgnoreCase)) ?? );
}
}
{
[] AllowedBrowsers { ; ; } = [];
}
builder.Services.AddFeatureManagement()
.AddFeatureFilter<BrowserFeatureFilter>();
```text
---
;
builder.Services
.AddOptions<ApiClientOptions>( )
.BindConfiguration( );
{
{
options = snapshot.Get(name);
HttpClient { BaseAddress = Uri(options.BaseUrl) };
}
}
```text
---
Apply defaults overrides after all configuration sources have been processed.
```csharp
builder.Services.PostConfigure<SmtpOptions>(options =>
{
(options.Port == )
{
options.Port = options.UseSsl ? : ;
}
});
```text
---
```csharp
[ ]
{
options = SmtpOptions
{
Host = ,
FromAddress = ,
Port = ,
UseSsl =
};
validator = SmtpOptionsValidator();
result = validator.Validate( , options);
Assert.True(result.Failed);
Assert.Contains( , result.FailureMessage);
}
[ ]
{
config = ConfigurationBuilder()
.AddInMemoryCollection( Dictionary< , ?>
{
[ ] = ,
[ ] = ,
[ ] = ,
})
.Build();
options = SmtpOptions();
config.GetSection( ).Bind(options);
Assert.Equal( , options.Host);
Assert.Equal( , options.Port);
}
```text
---
**Primary approach:** Use Serena symbol operations efficient code navigation:
**Find definitions**: `serena_find_symbol` instead of text search
**Understand structure**: `serena_get_symbols_overview` organization
**Track references**: `serena_find_referencing_symbols` impact analysis
**Precise edits**: `serena_replace_symbol_body` clean modifications
**When to use Serena vs traditional tools:**
- ✅ **Use Serena**: Navigation, refactoring, dependency analysis, precise edits
- ✅ **Use Read/Grep**: Reading full files, pattern matching, simple text operations
- ✅ **Fallback**: If Serena unavailable, traditional tools work fine
**Example workflow:**
```text
Read: src/Services/OrderService.cs
Grep:
serena_find_symbol:
serena_get_symbols_overview:
```
- [Options pattern .NET](https:
- [Configuration .NET](https:
- [User secrets development](https:
- [Feature management .NET](https:
- [IValidateOptions](https:
- [.NET Framework Design Guidelines](https:
"Smtp"
public
string
get
set
""
public
int
get
set
587
public
string
get
set
""
public
bool
get
set
true
get
set
not
init
and
for
### Registration
### `appsettings.json`
"Smtp"
"Host"
"smtp.example.com"
"Port"
587
"FromAddress"
"noreply@example.com"
"UseSsl"
true
## Options Interfaces
in
### Injection Examples
public sealed class EmailService (IOptions<SmtpOptions> options )
private
readonly
public Task SendAsync (string to, string subject, string body,
CancellationToken ct = default )
return
public sealed class FeatureService (IOptionsMonitor<FeatureOptions> monitor )
public bool IsEnabled (string feature )
public sealed class PricingService (IOptionsSnapshot<PricingOptions> snapshot )
public decimal GetMarkup ()
### Change Notifications with `IOptionsMonitor<T>`
public
sealed
class
CacheService
IDisposable
private
readonly
private
public CacheService (IOptionsMonitor<CacheOptions> monitor )
public void Dispose ()
## Options Validation
### Data Annotations
using
public
sealed
class
SmtpOptions
public
const
string
"Smtp"
Required, MinLength(1)
public
string
get
set
""
Range(1, 65535)
public
int
get
set
587
Required, EmailAddress
public
string
get
set
""
### `IValidateOptions<T>` (Complex Validation)
when
or
public
sealed
class
SmtpOptionsValidator
IValidateOptions
SmtpOptions
public ValidateOptionsResult Validate (string ? name, SmtpOptions options )
var
new
string
if
25
"Port 25 does not support SSL. Use 465 or 587."
if
string
"SMTP host is required."
return
0
### `ValidateOnStart` (Fail Fast)
when
is
## User Secrets (Development)
# Initialize (once per project)
init
# Set values
set
"Smtp:Host"
"smtp.example.com"
set
"ConnectionStrings:Default"
"Server=..."
# List all secrets
# Clear all
in
and
override
in
in
or
when
add
## Environment-Based Configuration
### Environment Variables
### Per-Environment Files
# Base (all environments)
# Overrides for dev
# Overrides for staging
# Overrides for prod
var
### Conditional Service Registration
csharp
if (builder.Environment.IsDevelopment( ))
else
## Feature Flags with Microsoft.FeatureManagement
with
and
### Setup
add
### Configuration
"FeatureManagement"
"NewDashboard"
true
"BetaSearch"
"EnabledFor"
"Name"
"Percentage"
"Parameters"
"Value"
50
"DarkMode"
"EnabledFor"
"Name"
"Targeting"
"Parameters"
"Audience"
"Users"
"alice@example.com"
"Groups"
"Name"
"Beta"
"RolloutPercentage"
100
"DefaultRolloutPercentage"
0
### Usage in Code
public sealed class DashboardController (IFeatureManager featureManager ) : ControllerBase
HttpGet
public async Task<IActionResult> Get (CancellationToken ct = default )
if
await
"NewDashboard"
return
new
"v2"
"new"
return
new
"v1"
"legacy"
### Feature Gate Attribute
FeatureGate("BetaSearch" )
HttpGet("search" )
public async Task<IActionResult> Search (string query, CancellationToken ct = default )
var
await
return
### Feature Filters
for
of requests (random ) |
| `TimeWindow` | Enable between start/end dates |
| `Targeting` | Enable for specific users, groups, or rollout percentage |
| Custom | Implement `IFeatureFilter` for domain-specific logic |
### Custom Feature Filter
```csharp
[FilterAlias ("Browser" )]
public sealed class BrowserFeatureFilter (IHttpContextAccessor accessor ) : IFeatureFilter
public Task<bool > EvaluateAsync (FeatureFilterEvaluationContext context )
var
""
var
return
false
public
sealed
class
BrowserFilterSettings
public
string
get
init
## Named Options
Use named options when you need multiple instances of the same options type (e.g., multiple API clients ).
```csharp
builder.Services
.AddOptions <ApiClientOptions >("GitHub" )
.BindConfiguration ("ApiClients:GitHub" )
"Jira"
"ApiClients:Jira"
public sealed class ApiClientFactory (IOptionsSnapshot<ApiClientOptions> snapshot )
public HttpClient CreateFor (string name )
var
return
new
new
## Post-Configuration
or
if
0
465
25
## Testing Configuration
Fact
public void SmtpOptions_Validates_InvalidPort ()
var
new
"smtp.example.com"
"test@example.com"
25
true
var
new
var
null
"Port 25 does not support SSL"
Fact
public void Configuration_BindsCorrectly ()
var
new
new
string
string
"Smtp:Host"
"smtp.test.com"
"Smtp:Port"
"465"
"Smtp:FromAddress"
"test@test.com"
var
new
"Smtp"
"smtp.test.com"
465
## Code Navigation (Serena MCP)
for
1.
2.
for
file
3.
for
4.
for
# Instead of:
"public void ProcessOrder"
# Use:
"OrderService/ProcessOrder"
"src/Services/OrderService.cs"
## References
in
in
in
in