Skip to main content

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");
// 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)

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. User Secrets (Development)
  4. Environment Variables
  5. 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

Resources