Configuration Management
Overview
ASP.NET Core uses a flexible configuration system that supports multiple sources: JSON files, environment variables, command-line arguments, Azure Key Vault, and more.
Configuration Sources
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=MyDb;..."
},
"ApiSettings": {
"ApiKey": "your-api-key",
"BaseUrl": "https://api.example.com",
"Timeout": 30
}
}
appsettings.{Environment}.json
// appsettings.Development.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=MyDb_Dev;..."
}
}
// appsettings.Production.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=prod-server;Database=MyDb_Prod;..."
}
}
Reading Configuration
Direct Access
var builder = WebApplication.CreateBuilder(args);
// Simple values
var apiKey = builder.Configuration["ApiSettings:ApiKey"];
var timeout = builder.Configuration.GetValue<int>("ApiSettings:Timeout");
// Connection strings
var connString = builder.Configuration.GetConnectionString("DefaultConnection");
Binding to POCO (Recommended)
// Settings class
public class ApiSettings
{
public string ApiKey { get; set; }
public string BaseUrl { get; set; }
public int Timeout { get; set; }
}
// Registration
builder.Services.Configure<ApiSettings>(
builder.Configuration.GetSection("ApiSettings"));
// Usage in service
public class MyService
{
private readonly ApiSettings _settings;
public MyService(IOptions<ApiSettings> options)
{
_settings = options.Value;
}
}
Options Pattern
IOptions<T>
- Singleton
- Does NOT support configuration reload
- Cannot read changes after app starts
public class MyService
{
private readonly ApiSettings _settings;
public MyService(IOptions<ApiSettings> options)
{
_settings = options.Value; // Read once
}
}
IOptionsSnapshot<T>
- Scoped
- Reloads configuration per request
- Use for changing configuration
public class MyService
{
private readonly IOptionsSnapshot<ApiSettings> _settings;
public MyService(IOptionsSnapshot<ApiSettings> settings)
{
_settings = settings; // Fresh config each request
}
public void DoWork()
{
var current = _settings.Value; // Latest config
}
}
IOptionsMonitor<T>
- Singleton
- Real-time reload notifications
- Use for background services
public class BackgroundService
{
private readonly IOptionsMonitor<ApiSettings> _settings;
public BackgroundService(IOptionsMonitor<ApiSettings> settings)
{
_settings = settings;
// Watch for changes
_settings.OnChange(newSettings =>
{
Console.WriteLine("Settings changed!");
});
}
public void DoWork()
{
var current = _settings.CurrentValue; // Always latest
}
}
Environment Variables
# Linux/Mac
export ApiSettings__ApiKey="prod-key"
export ConnectionStrings__DefaultConnection="Server=prod;..."
# Windows
set ApiSettings__ApiKey=prod-key
// Automatic override
var apiKey = builder.Configuration["ApiSettings:ApiKey"];
// Returns environment variable if set, otherwise appsettings.json value
User Secrets (Development)
# Initialize user secrets
dotnet user-secrets init
# Set secret
dotnet user-secrets set "ApiSettings:ApiKey" "dev-secret-key"
// Automatically loaded in Development environment
if (builder.Environment.IsDevelopment())
{
builder.Configuration.AddUserSecrets<Program>();
}
Azure Key Vault (Production)
builder.Configuration.AddAzureKeyVault(
new Uri($"https://{{keyVaultName}}.vault.azure.net/"),
new DefaultAzureCredential());
Configuration Priority (Last Wins)
- appsettings.json
- appsettings.{Environment}.json
- User Secrets (Development)
- Environment Variables
- Command-line Arguments
Interview Questions
Q: Difference between IOptions, IOptionsSnapshot, and IOptionsMonitor?
- IOptions: Singleton, no reload
- IOptionsSnapshot: Scoped, reloads per request
- IOptionsMonitor: Singleton, real-time reload with change notifications
Q: How do you secure sensitive configuration?
- Development: User Secrets
- Production: Environment variables, Azure Key Vault, AWS Secrets Manager