ASP.NET Core Configuration and Secrets Mastery: Complete Guide
Table of Contents
1. Introduction to Configuration in ASP.NET Core <a name="introduction"></a>
Configuration management is a critical aspect of modern web application development. In ASP.NET Core, the configuration system has been completely redesigned to be more flexible, extensible, and cloud-ready. Let's explore why proper configuration management is essential:
Why Configuration Management Matters
Real-Life Scenario: Imagine you're developing an e-commerce application that needs to connect to different databases in development, staging, and production environments. Without proper configuration management, you'd be constantly changing connection strings, risking security breaches and deployment failures.
// Problematic approach - hardcoded configuration public class DatabaseService { private string _connectionString = "Server=prod-db;Database=Shop;User=admin;Password=secret123"; public void Connect() { // This will fail in development and staging! } }
Evolution of Configuration in ASP.NET
From Web.config to Modern Approach:
ASP.NET Web Forms: XML-based Web.config with complex sections
ASP.NET MVC: Still Web.config with some improvements
ASP.NET Core: JSON-based, environment-aware, cloud-native
2. Understanding the Configuration System <a name="understanding-system"></a>
Configuration Building Blocks
The ASP.NET Core configuration system is built around several key concepts:
IConfiguration Interface
public interface IConfiguration { string this[string key] { get; set; } IConfigurationSection GetSection(string key); IEnumerable<IConfigurationSection> GetChildren(); IChangeToken GetReloadToken(); }
Configuration Sources Hierarchy
ASP.NET Core loads configuration from multiple sources in a specific order:
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { // Configuration sources are loaded in this order: // 1. appsettings.json // 2. appsettings.{Environment}.json // 3. User Secrets (Development environment only) // 4. Environment Variables // 5. Command-line arguments }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); }
Configuration Providers Deep Dive
// Detailed configuration setup with multiple providers public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { var env = context.HostingEnvironment; // Base appsettings config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); // Environment-specific appsettings config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); // User Secrets for development if (env.IsDevelopment()) { config.AddUserSecrets<Program>(); } // Environment variables config.AddEnvironmentVariables(); // Command-line arguments if (args != null) { config.AddCommandLine(args); } // Last provider wins - command line has highest priority });
3. AppSettings.json Deep Dive <a name="appsettings-json"></a>
Structured Configuration with JSON
Real-Life Example: E-commerce application configuration
{ "StoreSettings": { "StoreName": "TechMart Online", "MaxProductsPerPage": 50, "EnableWishlist": true, "Currency": "USD", "SupportedCountries": ["US", "CA", "UK", "AU"] }, "Database": { "ConnectionString": "Server=localhost;Database=TechMart;Trusted_Connection=true;", "Timeout": 30, "RetryCount": 3 }, "PaymentGateway": { "ApiKey": "pk_test_123456789", "BaseUrl": "https://api.payments.com/v1", "WebhookSecret": "whsec_987654321", "Settings": { "Timeout": 10000, "RetryPolicy": "ExponentialBackoff" } }, "EmailSettings": { "SmtpServer": "smtp.techmart.com", "Port": 587, "Username": "noreply@techmart.com", "FromAddress": "noreply@techmart.com", "Templates": { "OrderConfirmation": "templates/order-confirmation.html", "PasswordReset": "templates/password-reset.html" } }, "CacheSettings": { "RedisConnection": "localhost:6379", "DefaultExpiration": 3600, "Enabled": true }, "Security": { "Jwt": { "SecretKey": "your-super-secret-key-here", "Issuer": "TechMart", "Audience": "TechMartUsers", "ExpirationMinutes": 60 }, "Cors": { "AllowedOrigins": ["https://techmart.com", "https://admin.techmart.com"] } } }
Strongly-Typed Configuration Classes
// Configuration classes for strongly-typed access public class StoreSettings { public string StoreName { get; set; } public int MaxProductsPerPage { get; set; } public bool EnableWishlist { get; set; } public string Currency { get; set; } public string[] SupportedCountries { get; set; } } public class DatabaseSettings { public string ConnectionString { get; set; } public int Timeout { get; set; } public int RetryCount { get; set; } } public class PaymentGatewaySettings { public string ApiKey { get; set; } public string BaseUrl { get; set; } public string WebhookSecret { get; set; } public PaymentSettings Settings { get; set; } } public class PaymentSettings { public int Timeout { get; set; } public string RetryPolicy { get; set; } } public class EmailSettings { public string SmtpServer { get; set; } public int Port { get; set; } public string Username { get; set; } public string FromAddress { get; set; } public EmailTemplates Templates { get; set; } } public class EmailTemplates { public string OrderConfirmation { get; set; } public string PasswordReset { get; set; } } public class CacheSettings { public string RedisConnection { get; set; } public int DefaultExpiration { get; set; } public bool Enabled { get; set; } } public class SecuritySettings { public JwtSettings Jwt { get; set; } public CorsSettings Cors { get; set; } } public class JwtSettings { public string SecretKey { get; set; } public string Issuer { get; set; } public string Audience { get; set; } public int ExpirationMinutes { get; set; } } public class CorsSettings { public string[] AllowedOrigins { get; set; } }
Configuration Binding and Validation
// Startup configuration with validation public class Startup { private readonly IConfiguration _configuration; public Startup(IConfiguration configuration) { _configuration = configuration; } public void ConfigureServices(IServiceCollection services) { // Bind configuration sections to strongly-typed classes services.Configure<StoreSettings>(_configuration.GetSection("StoreSettings")); services.Configure<DatabaseSettings>(_configuration.GetSection("Database")); services.Configure<PaymentGatewaySettings>(_configuration.GetSection("PaymentGateway")); services.Configure<EmailSettings>(_configuration.GetSection("EmailSettings")); services.Configure<CacheSettings>(_configuration.GetSection("CacheSettings")); services.Configure<SecuritySettings>(_configuration.GetSection("Security")); // Advanced binding with validation var storeSettings = new StoreSettings(); _configuration.GetSection("StoreSettings").Bind(storeSettings); // Validate critical settings if (string.IsNullOrEmpty(storeSettings.StoreName)) { throw new InvalidOperationException("StoreName is required in configuration"); } // Register services that use configuration services.AddSingleton(storeSettings); // Database configuration with validation var dbSettings = _configuration.GetSection("Database").Get<DatabaseSettings>(); if (string.IsNullOrEmpty(dbSettings?.ConnectionString)) { throw new InvalidOperationException("Database connection string is required"); } services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(dbSettings.ConnectionString)); } }
4. Environment-Specific Configuration <a name="environment-config"></a>
Environment-Based Configuration Strategy
Real-Life Scenario: Different configurations for Development, Staging, and Production environments
// appsettings.Development.json { "Logging": { "LogLevel": { "Default": "Debug", "Microsoft": "Debug", "Microsoft.Hosting.Lifetime": "Debug" } }, "Database": { "ConnectionString": "Server=localhost;Database=TechMart_Dev;Trusted_Connection=true;", "Timeout": 30, "RetryCount": 3 }, "PaymentGateway": { "BaseUrl": "https://api.sandbox.payments.com/v1", "ApiKey": "pk_test_development_key" }, "Features": { "EnableSwagger": true, "EnableDetailedErrors": true, "UseInMemoryCache": true } } // appsettings.Staging.json { "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "Database": { "ConnectionString": "Server=staging-db.techmart.com;Database=TechMart_Staging;User Id=appuser;Password=staging_password;", "Timeout": 30, "RetryCount": 5 }, "PaymentGateway": { "BaseUrl": "https://api.staging.payments.com/v1", "ApiKey": "pk_test_staging_key" }, "Features": { "EnableSwagger": false, "EnableDetailedErrors": true, "UseInMemoryCache": false } } // appsettings.Production.json { "Logging": { "LogLevel": { "Default": "Warning", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Warning" } }, "Database": { "ConnectionString": "Server=prod-db.techmart.com;Database=TechMart_Prod;User Id=appuser;Password=production_password;", "Timeout": 30, "RetryCount": 5 }, "PaymentGateway": { "BaseUrl": "https://api.payments.com/v1", "ApiKey": "pk_live_production_key" }, "Features": { "EnableSwagger": false, "EnableDetailedErrors": false, "UseInMemoryCache": false } }
Environment Detection and Configuration
// Program.cs with environment-specific setup public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { var env = context.HostingEnvironment; Console.WriteLine($"Environment: {env.EnvironmentName}"); Console.WriteLine($"Content Root: {env.ContentRootPath}"); Console.WriteLine($"Web Root: {env.WebRootPath}"); // Load environment-specific configuration config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); // Additional configuration based on environment if (env.IsDevelopment()) { // Development-specific configuration config.AddUserSecrets<Program>(); } else if (env.IsStaging()) { // Staging-specific configuration config.AddJsonFile("appsettings.Staging.Secrets.json", optional: true, reloadOnChange: true); } else if (env.IsProduction()) { // Production-specific configuration // Rely on environment variables and secure vaults } }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); }
Environment-Based Service Registration
// Environment-specific service configuration public class Startup { public Startup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; Environment = env; } public IConfiguration Configuration { get; } public IWebHostEnvironment Environment { get; } public void ConfigureServices(IServiceCollection services) { // Common services for all environments services.AddControllers(); services.AddHttpClient(); // Environment-specific services if (Environment.IsDevelopment()) { services.AddDatabaseDeveloperPageExceptionFilter(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "TechMart API", Version = "v1" }); }); } // Database configuration based on environment if (Environment.IsDevelopment()) { services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")) .EnableSensitiveDataLogging()); } else { services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); } // Cache configuration if (Configuration.GetValue<bool>("Features:UseInMemoryCache")) { services.AddMemoryCache(); } else { var redisConnection = Configuration.GetValue<string>("CacheSettings:RedisConnection"); services.AddStackExchangeRedisCache(options => { options.Configuration = redisConnection; }); } } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TechMart API v1")); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
5. User Secrets for Development <a name="user-secrets"></a>
Why Use User Secrets?
Real-Life Problem: Developers committing sensitive data to source control
// Before User Secrets - sensitive data in appsettings.json { "ConnectionStrings": { "DefaultConnection": "Server=localhost;Database=MyApp;User Id=sa;Password=MySuperSecretPassword123!" }, "ApiKeys": { "SendGrid": "SG.abc123def456ghi789", "Stripe": "sk_test_1234567890abcdef" } }
Setting Up User Secrets
Step 1: Initialize User Secrets
# In the project directory
dotnet user-secrets initStep 2: Add Secrets
# Add connection string dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=localhost;Database=MyApp;User Id=sa;Password=DevPassword123!" # Add API keys dotnet user-secrets set "ApiKeys:SendGrid" "SG.devkey123456789" dotnet user-secrets set "ApiKeys:Stripe" "sk_test_devkey123456789" # Add JWT secret dotnet user-secrets set "Security:Jwt:SecretKey" "dev-super-secret-jwt-key-2024"
Step 3: secrets.json File Structure
{ "ConnectionStrings:DefaultConnection": "Server=localhost;Database=MyApp_Dev;User Id=sa;Password=DevPassword123!", "ApiKeys": { "SendGrid": "SG.devkey123456789", "Stripe": "sk_test_devkey123456789" }, "Security:Jwt:SecretKey": "dev-super-secret-jwt-key-2024", "PaymentGateway": { "ApiKey": "pk_test_dev_123456789", "WebhookSecret": "whsec_dev_987654321" } }
Programmatic Access to User Secrets
// Advanced User Secrets management public class DevelopmentSecretsManager { private readonly IConfiguration _configuration; public DevelopmentSecretsManager(IConfiguration configuration) { _configuration = configuration; } public void ValidateDevelopmentSecrets() { var requiredSecrets = new[] { "ConnectionStrings:DefaultConnection", "ApiKeys:SendGrid", "Security:Jwt:SecretKey" }; var missingSecrets = requiredSecrets .Where(secret => string.IsNullOrEmpty(_configuration[secret])) .ToList(); if (missingSecrets.Any()) { throw new InvalidOperationException( $"Missing required development secrets: {string.Join(", ", missingSecrets)}. " + "Run 'dotnet user-secrets set [key] [value]' to set them."); } } public string GetSecret(string key) { var value = _configuration[key]; if (string.IsNullOrEmpty(value)) { throw new ArgumentException($"Secret '{key}' not found in user secrets"); } return value; } public T GetSecret<T>(string key) { var value = GetSecret(key); return (T)Convert.ChangeType(value, typeof(T)); } } // Integration in Startup public class Startup { public Startup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; Environment = env; } public IConfiguration Configuration { get; } public IWebHostEnvironment Environment { get; } public void ConfigureServices(IServiceCollection services) { // Validate secrets in development if (Environment.IsDevelopment()) { var secretsManager = new DevelopmentSecretsManager(Configuration); secretsManager.ValidateDevelopmentSecrets(); } // Use secrets in services var connectionString = Configuration.GetConnectionString("DefaultConnection"); services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString)); } }
User Secrets Best Practices
// Secure development practices public static class SecretsBestPractices { public static void EnsureSecretsAreNotInAppSettings(IWebHostEnvironment env) { if (env.IsDevelopment()) { var appSettingsPath = Path.Combine(env.ContentRootPath, "appsettings.json"); var appSettingsContent = File.ReadAllText(appSettingsPath); var sensitivePatterns = new[] { @"password=([^;""']+)", @"pwd=([^;""']+)", @"api[_-]?key=([^;""']+)", @"secret=([^;""']+)" }; foreach (var pattern in sensitivePatterns) { var matches = System.Text.RegularExpressions.Regex.Matches(appSettingsContent, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase); if (matches.Count > 0) { throw new InvalidOperationException( "Sensitive data found in appsettings.json. Move to user secrets."); } } } } }
6. Environment Variables Configuration <a name="environment-variables"></a>
Environment Variables in Different Environments
Real-Life Scenario: Deployment to various environments (Docker, Azure, AWS, Kubernetes)
// Environment variable configuration provider public static class EnvironmentVariablesConfig { public static void ConfigureEnvironmentVariables(this IConfigurationBuilder config) { config.AddEnvironmentVariables(); // Add prefix for application-specific variables config.AddEnvironmentVariables("TECHMART_"); } } // Usage in Program.cs public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { config.AddJsonFile("appsettings.json", optional: false) .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true) .AddEnvironmentVariables("TECHMART_") // Application-specific .AddEnvironmentVariables(); // All environment variables });
Environment Variable Naming Conventions
// Environment variable mapping examples public static class EnvVarConstants { // Database public const string DB_CONNECTION = "TECHMART_DB_CONNECTION"; public const string DB_TIMEOUT = "TECHMART_DB_TIMEOUT"; // API Keys public const string SENDGRID_API_KEY = "TECHMART_SENDGRID_API_KEY"; public const string STRIPE_API_KEY = "TECHMART_STRIPE_API_KEY"; // Application Settings public const string ENVIRONMENT = "ASPNETCORE_ENVIRONMENT"; public const string URLs = "ASPNETCORE_URLS"; // Feature Flags public const string FEATURE_SWAGGER = "TECHMART_FEATURE_SWAGGER"; public const string FEATURE_CACHE = "TECHMART_FEATURE_CACHE"; } // Environment variable helper class public class EnvironmentConfig { private readonly IConfiguration _configuration; public EnvironmentConfig(IConfiguration configuration) { _configuration = configuration; } public string DatabaseConnection => GetRequiredValue(EnvVarConstants.DB_CONNECTION); public string SendGridApiKey => GetRequiredValue(EnvVarConstants.SENDGRID_API_KEY); public bool EnableSwagger => GetValue(EnvVarConstants.FEATURE_SWAGGER, false); public int DatabaseTimeout => GetValue(EnvVarConstants.DB_TIMEOUT, 30); private string GetRequiredValue(string key) { var value = _configuration[key]; if (string.IsNullOrEmpty(value)) { throw new InvalidOperationException($"Required environment variable '{key}' is missing"); } return value; } private T GetValue<T>(string key, T defaultValue) { var value = _configuration[key]; if (string.IsNullOrEmpty(value)) { return defaultValue; } try { return (T)Convert.ChangeType(value, typeof(T)); } catch (Exception ex) { throw new InvalidOperationException( $"Unable to convert environment variable '{key}' value '{value}' to type {typeof(T).Name}", ex); } } }
Docker and Container Configuration
# Dockerfile with environment variables FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["TechMart.Web/TechMart.Web.csproj", "TechMart.Web/"] RUN dotnet restore "TechMart.Web/TechMart.Web.csproj" COPY . . WORKDIR "/src/TechMart.Web" RUN dotnet build "TechMart.Web.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "TechMart.Web.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . # Environment variables for container ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:80 ENV TECHMART_DB_TIMEOUT=30 ENV TECHMART_FEATURE_SWAGGER=false ENTRYPOINT ["dotnet", "TechMart.Web.dll"]
# docker-compose.yml with environment variables version: '3.8' services: techmart.web: image: techmart/web:latest build: context: . dockerfile: TechMart.Web/Dockerfile environment: - ASPNETCORE_ENVIRONMENT=Development - TECHMART_DB_CONNECTION=Server=techmart.db;Database=TechMart_Dev;User Id=sa;Password=DevPassword123! - TECHMART_SENDGRID_API_KEY=SG.docker_dev_key - TECHMART_STRIPE_API_KEY=sk_test_docker_key - TECHMART_FEATURE_SWAGGER=true ports: - "5000:80" depends_on: - techmart.db techmart.db: image: mcr.microsoft.com/mssql/server:2019-latest environment: - SA_PASSWORD=DevPassword123! - ACCEPT_EULA=Y ports: - "1433:1433"
7. Command-Line Configuration <a name="command-line"></a>
Command-Line Arguments in ASP.NET Core
Real-Life Scenario: Overriding configuration for specific deployments or debugging
// Command-line configuration setup public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { // Configure command-line arguments with custom mappings var switchMappings = new Dictionary<string, string> { { "--urls", "urls" }, { "--environment", "environment" }, { "--db-connection", "ConnectionStrings:DefaultConnection" }, { "--enable-swagger", "Features:EnableSwagger" }, { "--cache-timeout", "CacheSettings:DefaultExpiration" }, { "--log-level", "Logging:LogLevel:Default" } }; config.AddCommandLine(args, switchMappings); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); }
Advanced Command-Line Processing
// Custom command-line argument processor public class CommandLineConfig { private readonly string[] _args; public CommandLineConfig(string[] args) { _args = args; } public Dictionary<string, string> ParseArguments() { var config = new Dictionary<string, string>(); for (int i = 0; i < _args.Length; i++) { var arg = _args[i]; if (arg.StartsWith("--")) { var key = arg.Substring(2); string value = "true"; // Default for flags // Check if next argument is a value (not another flag) if (i + 1 < _args.Length && !_args[i + 1].StartsWith("--")) { value = _args[i + 1]; i++; // Skip the value in next iteration } config[key] = value; } else if (arg.StartsWith("/")) { // Windows-style arguments: /key value or /key:value var parts = arg.Substring(1).Split(':'); var key = parts[0]; var value = parts.Length > 1 ? parts[1] : "true"; config[key] = value; } else if (arg.Contains("=")) { // Key=value format var parts = arg.Split('='); if (parts.Length == 2) { config[parts[0]] = parts[1]; } } } return config; } public void ValidateRequiredArguments(Dictionary<string, string> arguments) { var requiredArgs = new[] { "db-connection", "environment" }; var missingArgs = requiredArgs.Where(arg => !arguments.ContainsKey(arg)).ToList(); if (missingArgs.Any()) { throw new ArgumentException( $"Missing required command-line arguments: {string.Join(", ", missingArgs)}"); } } } // Integration with configuration public static class CommandLineConfigExtensions { public static IConfigurationBuilder AddCustomCommandLine( this IConfigurationBuilder builder, string[] args) { var commandLineConfig = new CommandLineConfig(args); var arguments = commandLineConfig.ParseArguments(); // Validate required arguments commandLineConfig.ValidateRequiredArguments(arguments); // Add to configuration foreach (var (key, value) in arguments) { Environment.SetEnvironmentVariable($"CMDLINE_{key}", value); } return builder.AddInMemoryCollection(arguments); } }
Real-World Command-Line Usage Examples
# Development with specific settings dotnet run --urls "https://localhost:5001" --environment "Development" --db-connection "Server=localhost;Database=DevDB;Trusted_Connection=true" --enable-swagger true --log-level "Debug" # Production with minimal logging dotnet run --urls "http://*:80" --environment "Production" --db-connection "Server=prod-db;Database=ProdDB;User Id=appuser;Password=ProdPass123!" --enable-swagger false --log-level "Warning" # Docker container with environment overrides docker run -p 8080:80 techmart/app --db-connection "Server=sql-server;Database=AppDB;User Id=sa;Password=DockerPass123!" --cache-timeout 3600
8. Custom Configuration Providers <a name="custom-providers"></a>
Building Custom Configuration Providers
Real-Life Scenario: Reading configuration from a custom XML file or external service
// Custom XML configuration provider public class XmlConfigurationProvider : ConfigurationProvider { private readonly string _filePath; public XmlConfigurationProvider(string filePath) { _filePath = filePath; } public override void Load() { var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); try { if (File.Exists(_filePath)) { var doc = XDocument.Load(_filePath); ParseXmlElement(doc.Root, "", data); } } catch (Exception ex) { throw new InvalidOperationException($"Failed to load XML configuration from {_filePath}", ex); } Data = data; } private void ParseXmlElement(XElement element, string prefix, Dictionary<string, string> data) { foreach (var child in element.Elements()) { var currentKey = string.IsNullOrEmpty(prefix) ? child.Name.LocalName : $"{prefix}:{child.Name.LocalName}"; if (child.HasElements) { ParseXmlElement(child, currentKey, data); } else { data[currentKey] = child.Value; } } } } public class XmlConfigurationSource : IConfigurationSource { public string FilePath { get; set; } public IConfigurationProvider Build(IConfigurationBuilder builder) { return new XmlConfigurationProvider(FilePath); } } public static class XmlConfigurationExtensions { public static IConfigurationBuilder AddXmlFile( this IConfigurationBuilder builder, string path, bool optional = false) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (string.IsNullOrEmpty(path)) { throw new ArgumentException("File path must not be null or empty", nameof(path)); } var source = new XmlConfigurationSource { FilePath = path, Optional = optional }; builder.Add(source); return builder; } }
Database Configuration Provider
// Database configuration provider for dynamic configuration public class DatabaseConfigurationProvider : ConfigurationProvider, IDisposable { private readonly DatabaseConfigurationSource _source; private readonly Timer _refreshTimer; private bool _disposed = false; public DatabaseConfigurationProvider(DatabaseConfigurationSource source) { _source = source; if (_source.ReloadOnChange && _source.ReloadInterval > 0) { _refreshTimer = new Timer(RefreshConfiguration, null, TimeSpan.FromSeconds(_source.ReloadInterval), TimeSpan.FromSeconds(_source.ReloadInterval)); } } public override void Load() { RefreshConfiguration(); } private void RefreshConfiguration(object state = null) { try { var newData = LoadConfigurationFromDatabase(); // Only update if configuration changed if (!Data.SequenceEqual(newData)) { Data = newData; OnReload(); // Notify about configuration changes } } catch (Exception ex) { // Log error but don't crash the application Console.WriteLine($"Failed to refresh configuration from database: {ex.Message}"); } } private Dictionary<string, string> LoadConfigurationFromDatabase() { var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); using var connection = new SqlConnection(_source.ConnectionString); connection.Open(); var command = new SqlCommand( "SELECT [Key], [Value], [Environment] FROM Configuration WHERE [Environment] = @Environment OR [Environment] IS NULL", connection); command.Parameters.AddWithValue("@Environment", _source.Environment); using var reader = command.ExecuteReader(); while (reader.Read()) { var key = reader.GetString(0); var value = reader.GetString(1); data[key] = value; } return data; } public void Dispose() { if (!_disposed) { _refreshTimer?.Dispose(); _disposed = true; } } } public class DatabaseConfigurationSource : IConfigurationSource { public string ConnectionString { get; set; } public string Environment { get; set; } public bool ReloadOnChange { get; set; } public int ReloadInterval { get; set; } = 30; // seconds public IConfigurationProvider Build(IConfigurationBuilder builder) { return new DatabaseConfigurationProvider(this); } } public static class DatabaseConfigurationExtensions { public static IConfigurationBuilder AddDatabaseConfiguration( this IConfigurationBuilder builder, string connectionString, string environment, bool reloadOnChange = false, int reloadInterval = 30) { return builder.Add(new DatabaseConfigurationSource { ConnectionString = connectionString, Environment = environment, ReloadOnChange = reloadOnChange, ReloadInterval = reloadInterval }); } }
9. Azure Key Vault Integration <a name="azure-key-vault"></a>
Securing Secrets with Azure Key Vault
Real-Life Scenario: Enterprise application with multiple environments and compliance requirements
// Azure Key Vault configuration provider public class Program { public static async Task Main(string[] args) { var host = CreateHostBuilder(args).Build(); // Validate Key Vault connectivity await ValidateKeyVaultConnection(host.Services); await host.RunAsync(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { var builtConfig = config.Build(); // Add Azure Key Vault var keyVaultEndpoint = builtConfig["AzureKeyVault:Endpoint"]; if (!string.IsNullOrEmpty(keyVaultEndpoint)) { var azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback( azureServiceTokenProvider.KeyVaultTokenCallback)); config.AddAzureKeyVault( keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager()); } }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); private static async Task ValidateKeyVaultConnection(IServiceProvider services) { try { var configuration = services.GetRequiredService<IConfiguration>(); var keyVaultEndpoint = configuration["AzureKeyVault:Endpoint"]; if (!string.IsNullOrEmpty(keyVaultEndpoint)) { var secretClient = new SecretClient(new Uri(keyVaultEndpoint), new DefaultAzureCredential()); // Test connection by trying to list secrets await secretClient.GetPropertiesOfSecretsAsync().FirstAsync(); Console.WriteLine("✅ Azure Key Vault connection successful"); } } catch (Exception ex) { Console.WriteLine($"❌ Azure Key Vault connection failed: {ex.Message}"); throw; } } }
Advanced Key Vault Management
// Key Vault secret management service public class KeyVaultSecretManager { private readonly SecretClient _secretClient; private readonly ILogger<KeyVaultSecretManager> _logger; public KeyVaultSecretManager(IConfiguration configuration, ILogger<KeyVaultSecretManager> logger) { var keyVaultEndpoint = configuration["AzureKeyVault:Endpoint"]; if (string.IsNullOrEmpty(keyVaultEndpoint)) { throw new InvalidOperationException("Azure Key Vault endpoint is not configured"); } _secretClient = new SecretClient(new Uri(keyVaultEndpoint), new DefaultAzureCredential()); _logger = logger; } public async Task<string> GetSecretAsync(string secretName) { try { var secret = await _secretClient.GetSecretAsync(secretName); return secret.Value.Value; } catch (RequestFailedException ex) when (ex.Status == 404) { _logger.LogWarning("Secret '{SecretName}' not found in Key Vault", secretName); return null; } catch (Exception ex) { _logger.LogError(ex, "Failed to retrieve secret '{SecretName}' from Key Vault", secretName); throw; } } public async Task SetSecretAsync(string secretName, string secretValue) { try { await _secretClient.SetSecretAsync(secretName, secretValue); _logger.LogInformation("Secret '{SecretName}' updated in Key Vault", secretName); } catch (Exception ex) { _logger.LogError(ex, "Failed to set secret '{SecretName}' in Key Vault", secretName); throw; } } public async Task<IEnumerable<string>> ListSecretsAsync() { var secrets = new List<string>(); await foreach (var secretProperties in _secretClient.GetPropertiesOfSecretsAsync()) { secrets.Add(secretProperties.Name); } return secrets; } public async Task<bool> SecretExistsAsync(string secretName) { try { await _secretClient.GetSecretAsync(secretName); return true; } catch (RequestFailedException ex) when (ex.Status == 404) { return false; } } } // Startup configuration for Key Vault public class Startup { public Startup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; Environment = env; } public IConfiguration Configuration { get; } public IWebHostEnvironment Environment { get; } public void ConfigureServices(IServiceCollection services) { // Register Key Vault service services.AddSingleton<KeyVaultSecretManager>(); // Configure database using Key Vault services.AddDbContext<ApplicationDbContext>(options => { var connectionString = Configuration.GetConnectionString("DefaultConnection"); options.UseSqlServer(connectionString); }); // Configure other services with secrets from Key Vault services.Configure<PaymentGatewaySettings>(options => { options.ApiKey = Configuration["PaymentGateway--ApiKey"]; options.WebhookSecret = Configuration["PaymentGateway--WebhookSecret"]; }); } }
Key Vault Secret Rotation
// Secret rotation service public class SecretRotationService : BackgroundService { private readonly KeyVaultSecretManager _secretManager; private readonly IConfiguration _configuration; private readonly ILogger<SecretRotationService> _logger; public SecretRotationService( KeyVaultSecretManager secretManager, IConfiguration configuration, ILogger<SecretRotationService> logger) { _secretManager = secretManager; _configuration = configuration; _logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { try { await RotateSecretsIfNeeded(); await Task.Delay(TimeSpan.FromHours(24), stoppingToken); // Check daily } catch (Exception ex) { _logger.LogError(ex, "Secret rotation failed"); await Task.Delay(TimeSpan.FromHours(1), stoppingToken); // Retry after 1 hour } } } private async Task RotateSecretsIfNeeded() { var secretsToRotate = new[] { "DatabasePassword", "ApiKey--Primary", "JwtSecret" }; foreach (var secretName in secretsToRotate) { if (await ShouldRotateSecret(secretName)) { await RotateSecret(secretName); } } } private async Task<bool> ShouldRotateSecret(string secretName) { // Check secret age or other rotation criteria var secret = await _secretManager.GetSecretAsync(secretName); if (secret == null) return false; // Implement rotation logic based on your requirements return false; // Placeholder } private async Task RotateSecret(string secretName) { _logger.LogInformation("Rotating secret: {SecretName}", secretName); // Generate new secret value var newSecretValue = GenerateNewSecret(secretName); // Set new version in Key Vault await _secretManager.SetSecretAsync(secretName, newSecretValue); _logger.LogInformation("Successfully rotated secret: {SecretName}", secretName); } private string GenerateNewSecret(string secretName) { return secretName switch { "DatabasePassword" => GenerateSecurePassword(), "ApiKey--Primary" => GenerateApiKey(), "JwtSecret" => GenerateJwtSecret(), _ => Guid.NewGuid().ToString() }; } private string GenerateSecurePassword() { const string validChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*"; var random = new Random(); return new string(Enumerable.Repeat(validChars, 32) .Select(s => s[random.Next(s.Length)]).ToArray()); } private string GenerateApiKey() => $"key_{Guid.NewGuid():N}"; private string GenerateJwtSecret() => Convert.ToBase64String(Guid.NewGuid().ToByteArray()); }
10. AWS Secrets Manager <a name="aws-secrets"></a>
AWS Secrets Manager Integration
Real-Life Scenario: Multi-cloud deployment with AWS infrastructure
// AWS Secrets Manager configuration provider public class AwsSecretsManagerConfigurationProvider : ConfigurationProvider { private readonly string _region; private readonly string _secretName; private readonly IAmazonSecretsManager _secretsClient; public AwsSecretsManagerConfigurationProvider(string region, string secretName) { _region = region; _secretName = secretName; _secretsClient = new AmazonSecretsManagerClient(RegionEndpoint.GetBySystemName(region)); } public override void Load() { try { var secret = GetSecretValueAsync().GetAwaiter().GetResult(); var data = ParseSecretString(secret); Data = data; } catch (Exception ex) { throw new InvalidOperationException($"Failed to load secrets from AWS Secrets Manager: {ex.Message}", ex); } } private async Task<string> GetSecretValueAsync() { var request = new GetSecretValueRequest { SecretId = _secretName }; var response = await _secretsClient.GetSecretValueAsync(request); return response.SecretString; } private Dictionary<string, string> ParseSecretString(string secretString) { var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); try { var json = JsonDocument.Parse(secretString); ParseJsonElement(json.RootElement, "", data); } catch (JsonException) { // If not JSON, treat as simple key-value pairs data[_secretName] = secretString; } return data; } private void ParseJsonElement(JsonElement element, string prefix, Dictionary<string, string> data) { switch (element.ValueKind) { case JsonValueKind.Object: foreach (var property in element.EnumerateObject()) { var currentKey = string.IsNullOrEmpty(prefix) ? property.Name : $"{prefix}:{property.Name}"; ParseJsonElement(property.Value, currentKey, data); } break; case JsonValueKind.Array: var index = 0; foreach (var item in element.EnumerateArray()) { var currentKey = $"{prefix}:{index}"; ParseJsonElement(item, currentKey, data); index++; } break; default: data[prefix] = element.ToString(); break; } } } public class AwsSecretsManagerConfigurationSource : IConfigurationSource { public string Region { get; set; } public string SecretName { get; set; } public IConfigurationProvider Build(IConfigurationBuilder builder) { return new AwsSecretsManagerConfigurationProvider(Region, SecretName); } } public static class AwsSecretsManagerConfigurationExtensions { public static IConfigurationBuilder AddAwsSecretsManager( this IConfigurationBuilder builder, string region, string secretName) { return builder.Add(new AwsSecretsManagerConfigurationSource { Region = region, SecretName = secretName }); } }
Multi-Cloud Secret Management
// Unified secret management service public interface ISecretManager { Task<string> GetSecretAsync(string secretName); Task SetSecretAsync(string secretName, string secretValue); Task<bool> SecretExistsAsync(string secretName); } public class MultiCloudSecretManager : ISecretManager { private readonly KeyVaultSecretManager _azureSecretManager; private readonly AwsSecretManager _awsSecretManager; private readonly IConfiguration _configuration; private readonly ILogger<MultiCloudSecretManager> _logger; public MultiCloudSecretManager( KeyVaultSecretManager azureSecretManager, AwsSecretManager awsSecretManager, IConfiguration configuration, ILogger<MultiCloudSecretManager> logger) { _azureSecretManager = azureSecretManager; _awsSecretManager = awsSecretManager; _configuration = configuration; _logger = logger; } public async Task<string> GetSecretAsync(string secretName) { // Determine which cloud provider to use based on configuration var cloudProvider = _configuration["CloudProvider"] ?? "Azure"; try { return cloudProvider switch { "Azure" => await _azureSecretManager.GetSecretAsync(secretName), "AWS" => await _awsSecretManager.GetSecretAsync(secretName), _ => throw new InvalidOperationException($"Unsupported cloud provider: {cloudProvider}") }; } catch (Exception ex) { _logger.LogError(ex, "Failed to retrieve secret '{SecretName}' from {CloudProvider}", secretName, cloudProvider); throw; } } public async Task SetSecretAsync(string secretName, string secretValue) { var cloudProvider = _configuration["CloudProvider"] ?? "Azure"; try { switch (cloudProvider) { case "Azure": await _azureSecretManager.SetSecretAsync(secretName, secretValue); break; case "AWS": await _awsSecretManager.SetSecretAsync(secretName, secretValue); break; default: throw new InvalidOperationException($"Unsupported cloud provider: {cloudProvider}"); } _logger.LogInformation("Secret '{SecretName}' updated in {CloudProvider}", secretName, cloudProvider); } catch (Exception ex) { _logger.LogError(ex, "Failed to set secret '{SecretName}' in {CloudProvider}", secretName, cloudProvider); throw; } } public async Task<bool> SecretExistsAsync(string secretName) { var cloudProvider = _configuration["CloudProvider"] ?? "Azure"; return cloudProvider switch { "Azure" => await _azureSecretManager.SecretExistsAsync(secretName), "AWS" => await _awsSecretManager.SecretExistsAsync(secretName), _ => throw new InvalidOperationException($"Unsupported cloud provider: {cloudProvider}") }; } } // AWS Secret Manager implementation public class AwsSecretManager { private readonly IAmazonSecretsManager _secretsClient; private readonly ILogger<AwsSecretManager> _logger; public AwsSecretManager(string region, ILogger<AwsSecretManager> logger) { _secretsClient = new AmazonSecretsManagerClient(RegionEndpoint.GetBySystemName(region)); _logger = logger; } public async Task<string> GetSecretAsync(string secretName) { try { var request = new GetSecretValueRequest { SecretId = secretName }; var response = await _secretsClient.GetSecretValueAsync(request); return response.SecretString; } catch (ResourceNotFoundException) { _logger.LogWarning("Secret '{SecretName}' not found in AWS Secrets Manager", secretName); return null; } catch (Exception ex) { _logger.LogError(ex, "Failed to retrieve secret '{SecretName}' from AWS Secrets Manager", secretName); throw; } } public async Task SetSecretAsync(string secretName, string secretValue) { try { var request = new PutSecretValueRequest { SecretId = secretName, SecretString = secretValue }; await _secretsClient.PutSecretValueAsync(request); } catch (Exception ex) { _logger.LogError(ex, "Failed to set secret '{SecretName}' in AWS Secrets Manager", secretName); throw; } } public async Task<bool> SecretExistsAsync(string secretName) { try { await GetSecretAsync(secretName); return true; } catch (ResourceNotFoundException) { return false; } } }
11. Database Configuration Provider <a name="database-provider"></a>
Dynamic Database Configuration
Real-Life Scenario: Application that needs runtime configuration changes without redeployment
// Advanced database configuration provider public class DynamicDatabaseConfigurationProvider : ConfigurationProvider, IDisposable { private readonly DynamicDatabaseConfigurationSource _source; private readonly Timer _refreshTimer; private readonly ILogger<DynamicDatabaseConfigurationProvider> _logger; private bool _disposed = false; public DynamicDatabaseConfigurationProvider(DynamicDatabaseConfigurationSource source) { _source = source; _logger = source.LoggerFactory?.CreateLogger<DynamicDatabaseConfigurationProvider>(); if (_source.ReloadOnChange) { _refreshTimer = new Timer(async _ => await RefreshConfigurationAsync(), null, TimeSpan.FromSeconds(_source.ReloadInterval), TimeSpan.FromSeconds(_source.ReloadInterval)); } } public override void Load() { LoadAsync().GetAwaiter().GetResult(); } private async Task LoadAsync() { try { await RefreshConfigurationAsync(); } catch (Exception ex) { _logger?.LogError(ex, "Failed to load configuration from database"); throw; } } private async Task RefreshConfigurationAsync() { try { var newData = await LoadConfigurationFromDatabaseAsync(); if (!Data.SequenceEqual(newData)) { Data = newData; OnReload(); _logger?.LogInformation("Configuration reloaded from database"); } } catch (Exception ex) { _logger?.LogError(ex, "Failed to refresh configuration from database"); } } private async Task<Dictionary<string, string>> LoadConfigurationFromDatabaseAsync() { var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); await using var connection = new SqlConnection(_source.ConnectionString); await connection.OpenAsync(); var command = new SqlCommand(_source.Query, connection); command.Parameters.AddWithValue("@Environment", _source.Environment); command.Parameters.AddWithValue("@Application", _source.ApplicationName); await using var reader = await command.ExecuteReaderAsync(); while (await reader.ReadAsync()) { var key = reader.GetString(0); var value = reader.IsDBNull(1) ? null : reader.GetString(1); data[key] = value; } return data; } public void Dispose() { if (!_disposed) { _refreshTimer?.Dispose(); _disposed = true; } } } public class DynamicDatabaseConfigurationSource : IConfigurationSource { public string ConnectionString { get; set; } public string Query { get; set; } = "SELECT [Key], [Value] FROM Configuration WHERE ([Environment] = @Environment OR [Environment] IS NULL) AND ([Application] = @Application OR [Application] IS NULL)"; public string Environment { get; set; } public string ApplicationName { get; set; } public bool ReloadOnChange { get; set; } = true; public int ReloadInterval { get; set; } = 30; public ILoggerFactory LoggerFactory { get; set; } public IConfigurationProvider Build(IConfigurationBuilder builder) { return new DynamicDatabaseConfigurationProvider(this); } } public static class DynamicDatabaseConfigurationExtensions { public static IConfigurationBuilder AddDynamicDatabaseConfiguration( this IConfigurationBuilder builder, string connectionString, string environment, string applicationName = null, bool reloadOnChange = true, int reloadInterval = 30, ILoggerFactory loggerFactory = null) { return builder.Add(new DynamicDatabaseConfigurationSource { ConnectionString = connectionString, Environment = environment, ApplicationName = applicationName, ReloadOnChange = reloadOnChange, ReloadInterval = reloadInterval, LoggerFactory = loggerFactory }); } }
Configuration Management API
// API for managing configuration in database [ApiController] [Route("api/[controller]")] public class ConfigurationController : ControllerBase { private readonly ApplicationDbContext _context; private readonly IConfiguration _configuration; private readonly ILogger<ConfigurationController> _logger; public ConfigurationController( ApplicationDbContext context, IConfiguration configuration, ILogger<ConfigurationController> logger) { _context = context; _configuration = configuration; _logger = logger; } [HttpGet] public async Task<ActionResult<IEnumerable<ConfigurationItem>>> GetConfiguration( [FromQuery] string environment = null, [FromQuery] string application = null) { var query = _context.Configuration.AsQueryable(); if (!string.IsNullOrEmpty(environment)) { query = query.Where(c => c.Environment == environment || c.Environment == null); } if (!string.IsNullOrEmpty(application)) { query = query.Where(c => c.Application == application || c.Application == null); } var items = await query.ToListAsync(); return Ok(items); } [HttpPost] public async Task<ActionResult<ConfigurationItem>> CreateConfiguration( ConfigurationItem item) { // Validate the configuration key if (string.IsNullOrEmpty(item.Key)) { return BadRequest("Key is required"); } // Check if configuration already exists var existing = await _context.Configuration .Where(c => c.Key == item.Key && c.Environment == item.Environment && c.Application == item.Application) .FirstOrDefaultAsync(); if (existing != null) { return Conflict($"Configuration with key '{item.Key}' already exists"); } _context.Configuration.Add(item); await _context.SaveChangesAsync(); _logger.LogInformation("Configuration created: {Key} for {Environment}/{Application}", item.Key, item.Environment, item.Application); return CreatedAtAction(nameof(GetConfigurationItem), new { id = item.Id }, item); } [HttpPut("{id}")] public async Task<IActionResult> UpdateConfiguration(int id, ConfigurationItem item) { if (id != item.Id) { return BadRequest(); } var existing = await _context.Configuration.FindAsync(id); if (existing == null) { return NotFound(); } existing.Value = item.Value; existing.UpdatedAt = DateTime.UtcNow; existing.UpdatedBy = User.Identity.Name; await _context.SaveChangesAsync(); _logger.LogInformation("Configuration updated: {Key}", existing.Key); return NoContent(); } [HttpDelete("{id}")] public async Task<IActionResult> DeleteConfiguration(int id) { var item = await _context.Configuration.FindAsync(id); if (item == null) { return NotFound(); } _context.Configuration.Remove(item); await _context.SaveChangesAsync(); _logger.LogInformation("Configuration deleted: {Key}", item.Key); return NoContent(); } [HttpGet("{id}")] public async Task<ActionResult<ConfigurationItem>> GetConfigurationItem(int id) { var item = await _context.Configuration.FindAsync(id); if (item == null) { return NotFound(); } return item; } } // Configuration entity model public class ConfigurationItem { public int Id { get; set; } [Required] [StringLength(200)] public string Key { get; set; } public string Value { get; set; } [StringLength(50)] public string Environment { get; set; } [StringLength(50)] public string Application { get; set; } public string Description { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public string CreatedBy { get; set; } public DateTime? UpdatedAt { get; set; } public string UpdatedBy { get; set; } public bool IsSensitive { get; set; } }
12. Configuration Best Practices <a name="best-practices"></a>
Security Best Practices
// Security-focused configuration validation public class SecurityConfigurationValidator { private readonly IConfiguration _configuration; private readonly ILogger<SecurityConfigurationValidator> _logger; public SecurityConfigurationValidator( IConfiguration configuration, ILogger<SecurityConfigurationValidator> logger) { _configuration = configuration; _logger = logger; } public void ValidateSecuritySettings() { ValidateNoSecretsInAppSettings(); ValidateConnectionStrings(); ValidateApiKeys(); ValidateJwtSettings(); } private void ValidateNoSecretsInAppSettings() { var appSettingsPath = "appsettings.json"; if (File.Exists(appSettingsPath)) { var content = File.ReadAllText(appSettingsPath); var sensitivePatterns = new[] { @"(?i)password[=:""']([^""']+)", @"(?i)pwd[=:""']([^""']+)", @"(?i)secret[=:""']([^""']+)", @"(?i)key[=:""']([^""']+)", @"(?i)token[=:""']([^""']+)", @"sk_live_[a-zA-Z0-9]+", @"SG\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+" }; foreach (var pattern in sensitivePatterns) { var matches = System.Text.RegularExpressions.Regex.Matches(content, pattern); if (matches.Count > 0) { _logger.LogWarning( "Potential secrets found in appsettings.json. Pattern: {Pattern}. " + "Consider moving these to secure storage.", pattern); } } } } private void ValidateConnectionStrings() { var connectionStrings = _configuration.GetSection("ConnectionStrings").GetChildren(); foreach (var connectionString in connectionStrings) { if (string.IsNullOrEmpty(connectionString.Value)) { throw new InvalidOperationException( $"Connection string '{connectionString.Key}' is empty"); } // Check for weak passwords in connection strings if (ContainsWeakPassword(connectionString.Value)) { _logger.LogWarning( "Connection string '{Key}' may contain weak password", connectionString.Key); } } } private void ValidateApiKeys() { var apiKeysSection = _configuration.GetSection("ApiKeys"); if (apiKeysSection.Exists()) { foreach (var apiKey in apiKeysSection.GetChildren()) { if (string.IsNullOrEmpty(apiKey.Value)) { throw new InvalidOperationException($"API key '{apiKey.Key}' is empty"); } if (apiKey.Value.Length < 16) { _logger.LogWarning("API key '{Key}' may be too short", apiKey.Key); } } } } private void ValidateJwtSettings() { var jwtSection = _configuration.GetSection("Security:Jwt"); if (jwtSection.Exists()) { var secretKey = jwtSection["SecretKey"]; if (string.IsNullOrEmpty(secretKey)) { throw new InvalidOperationException("JWT secret key is required"); } if (secretKey.Length < 32) { throw new InvalidOperationException( "JWT secret key must be at least 32 characters long"); } if (secretKey.Equals("your-super-secret-key-here", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException( "JWT secret key must be changed from the default value"); } } } private bool ContainsWeakPassword(string connectionString) { var weakPasswords = new[] { "password", "123456", "admin", "sa", "test" }; return weakPasswords.Any(weak => connectionString.Contains($"Password={weak}") || connectionString.Contains($"Pwd={weak}")); } }
Performance Optimization
// Configuration performance optimization public class OptimizedConfigurationService { private readonly IConfiguration _configuration; private readonly ConcurrentDictionary<string, object> _cache; private readonly TimeSpan _cacheDuration; public OptimizedConfigurationService(IConfiguration configuration) { _configuration = configuration; _cache = new ConcurrentDictionary<string, object>(); _cacheDuration = TimeSpan.FromMinutes(5); } public T GetValue<T>(string key, T defaultValue = default) { var cacheKey = $"{typeof(T).Name}:{key}"; if (_cache.TryGetValue(cacheKey, out var cachedValue) && cachedValue is CacheItem<T> cacheItem && cacheItem.Expiry > DateTime.UtcNow) { return cacheItem.Value; } var value = _configuration.GetValue(key, defaultValue); _cache[cacheKey] = new CacheItem<T>(value, DateTime.UtcNow.Add(_cacheDuration)); return value; } public T GetSection<T>(string sectionKey) where T : class, new() { var cacheKey = $"{typeof(T).Name}:{sectionKey}"; if (_cache.TryGetValue(cacheKey, out var cachedValue) && cachedValue is CacheItem<T> cacheItem && cacheItem.Expiry > DateTime.UtcNow) { return cacheItem.Value; } var section = _configuration.GetSection(sectionKey); var value = new T(); section.Bind(value); _cache[cacheKey] = new CacheItem<T>(value, DateTime.UtcNow.Add(_cacheDuration)); return value; } public void ClearCache() { _cache.Clear(); } public void RemoveFromCache(string key) { _cache.TryRemove(key, out _); } private class CacheItem<T> { public T Value { get; } public DateTime Expiry { get; } public CacheItem(T value, DateTime expiry) { Value = value; Expiry = expiry; } } } // Configuration change detection and cache invalidation public class ConfigurationChangeNotifier : IDisposable { private readonly IConfiguration _configuration; private readonly OptimizedConfigurationService _configService; private readonly ILogger<ConfigurationChangeNotifier> _logger; private readonly List<IDisposable> _changeCallbacks; public ConfigurationChangeNotifier( IConfiguration configuration, OptimizedConfigurationService configService, ILogger<ConfigurationChangeNotifier> logger) { _configuration = configuration; _configService = configService; _logger = logger; _changeCallbacks = new List<IDisposable>(); SetupChangeDetection(); } private void SetupChangeDetection() { // Monitor specific sections for changes var sectionsToMonitor = new[] { "Database", "Features", "CacheSettings" }; foreach (var section in sectionsToMonitor) { var changeToken = _configuration.GetReloadToken(); var callback = changeToken.RegisterChangeCallback(_ => OnConfigurationChanged(section), section); _changeCallbacks.Add(callback); } } private void OnConfigurationChanged(string section) { _logger.LogInformation("Configuration section '{Section}' changed, clearing cache", section); _configService.ClearCache(); // Re-register for changes SetupChangeDetection(); } public void Dispose() { foreach (var callback in _changeCallbacks) { callback?.Dispose(); } _changeCallbacks.Clear(); } }
13. Security Considerations <a name="security"></a>
Comprehensive Security Validation
// Advanced security configuration analyzer public class SecurityConfigurationAnalyzer { private readonly IConfiguration _configuration; private readonly IWebHostEnvironment _environment; private readonly ILogger<SecurityConfigurationAnalyzer> _logger; public SecurityConfigurationAnalyzer( IConfiguration configuration, IWebHostEnvironment environment, ILogger<SecurityConfigurationAnalyzer> logger) { _configuration = configuration; _environment = environment; _logger = logger; } public SecurityAnalysisResult Analyze() { var result = new SecurityAnalysisResult(); result.Issues.AddRange(CheckForHardcodedSecrets()); result.Issues.AddRange(CheckWeakEncryption()); result.Issues.AddRange(CheckInsecureProtocols()); result.Issues.AddRange(CheckExposedEndpoints()); result.Issues.AddRange(CheckCorsSettings()); result.Issues.AddRange(CheckJwtSecurity()); result.Score = CalculateSecurityScore(result.Issues); return result; } private IEnumerable<SecurityIssue> CheckForHardcodedSecrets() { var issues = new List<SecurityIssue>(); // Check appsettings for common secret patterns var appSettingsPath = Path.Combine(_environment.ContentRootPath, "appsettings.json"); if (File.Exists(appSettingsPath)) { var content = File.ReadAllText(appSettingsPath); var secretPatterns = new[] { new { Pattern = @"(?i)[""']?password[""']?\s*[:=]\s*[""']([^""']+)[""']", Type = "Hardcoded Password" }, new { Pattern = @"(?i)[""']?apikey[""']?\s*[:=]\s*[""']([^""']+)[""']", Type = "Hardcoded API Key" }, new { Pattern = @"(?i)[""']?secret[""']?\s*[:=]\s*[""']([^""']+)[""']", Type = "Hardcoded Secret" }, new { Pattern = @"sk_live_[a-zA-Z0-9]{24}", Type = "Stripe Secret Key" }, new { Pattern = @"SG\.[a-zA-Z0-9_-]{22}\.[a-zA-Z0-9_-]{43}", Type = "SendGrid API Key" } }; foreach (var pattern in secretPatterns) { var matches = System.Text.RegularExpressions.Regex.Matches(content, pattern.Pattern); foreach (Match match in matches) { issues.Add(new SecurityIssue { Type = pattern.Type, Severity = SecuritySeverity.High, Message = $"{pattern.Type} found in appsettings.json", Recommendation = "Move to secure storage like Azure Key Vault or AWS Secrets Manager" }); } } } return issues; } private IEnumerable<SecurityIssue> CheckWeakEncryption() { var issues = new List<SecurityIssue>(); var jwtSecret = _configuration["Security:Jwt:SecretKey"]; if (!string.IsNullOrEmpty(jwtSecret) && jwtSecret.Length < 32) { issues.Add(new SecurityIssue { Type = "Weak JWT Secret", Severity = SecuritySeverity.High, Message = "JWT secret key is too short (minimum 32 characters recommended)", Recommendation = "Generate a strong random secret key with at least 32 characters" }); } return issues; } private IEnumerable<SecurityIssue> CheckInsecureProtocols() { var issues = new List<SecurityIssue>(); var paymentUrl = _configuration["PaymentGateway:BaseUrl"]; if (!string.IsNullOrEmpty(paymentUrl) && paymentUrl.StartsWith("http://")) { issues.Add(new SecurityIssue { Type = "Insecure Protocol", Severity = SecuritySeverity.Medium, Message = "Payment gateway URL uses HTTP instead of HTTPS", Recommendation = "Use HTTPS for all external service communications" }); } return issues; } private IEnumerable<SecurityIssue> CheckExposedEndpoints() { var issues = new List<SecurityIssue>(); if (_environment.IsProduction()) { var enableSwagger = _configuration.GetValue<bool>("Features:EnableSwagger"); if (enableSwagger) { issues.Add(new SecurityIssue { Type = "Exposed Development Tool", Severity = SecuritySeverity.Medium, Message = "Swagger is enabled in production environment", Recommendation = "Disable Swagger in production for security" }); } } return issues; } private IEnumerable<SecurityIssue> CheckCorsSettings() { var issues = new List<SecurityIssue>(); var corsOrigins = _configuration.GetSection("Security:Cors:AllowedOrigins").Get<string[]>(); if (corsOrigins != null && corsOrigins.Contains("*")) { issues.Add(new SecurityIssue { Type = "Overly Permissive CORS", Severity = SecuritySeverity.High, Message = "CORS policy allows all origins (*)", Recommendation = "Restrict CORS to specific trusted domains" }); } return issues; } private IEnumerable<SecurityIssue> CheckJwtSecurity() { var issues = new List<SecurityIssue>(); var expiration = _configuration.GetValue<int>("Security:Jwt:ExpirationMinutes"); if (expiration > 1440) // 24 hours { issues.Add(new SecurityIssue { Type = "Long JWT Expiration", Severity = SecuritySeverity.Medium, Message = $"JWT token expiration ({expiration} minutes) is too long", Recommendation = "Set JWT expiration to 15-60 minutes for better security" }); } return issues; } private int CalculateSecurityScore(List<SecurityIssue> issues) { var baseScore = 100; foreach (var issue in issues) { baseScore -= issue.Severity switch { SecuritySeverity.High => 20, SecuritySeverity.Medium => 10, SecuritySeverity.Low => 5, _ => 0 }; } return Math.Max(0, baseScore); } } public class SecurityAnalysisResult { public List<SecurityIssue> Issues { get; set; } = new List<SecurityIssue>(); public int Score { get; set; } public DateTime AnalyzedAt { get; set; } = DateTime.UtcNow; } public class SecurityIssue { public string Type { get; set; } public SecuritySeverity Severity { get; set; } public string Message { get; set; } public string Recommendation { get; set; } } public enum SecuritySeverity { Low, Medium, High }
14. Troubleshooting Common Issues <a name="troubleshooting"></a>
Configuration Troubleshooting Tools
// Comprehensive configuration diagnostics public class ConfigurationDiagnostics { private readonly IConfiguration _configuration; private readonly ILogger<ConfigurationDiagnostics> _logger; public ConfigurationDiagnostics(IConfiguration configuration, ILogger<ConfigurationDiagnostics> logger) { _configuration = configuration; _logger = logger; } public async Task<ConfigurationDiagnosticResult> RunDiagnosticsAsync() { var result = new ConfigurationDiagnosticResult(); result.Issues.AddRange(await CheckConfigurationSourcesAsync()); result.Issues.AddRange(CheckRequiredSettings()); result.Issues.AddRange(CheckConfigurationValues()); result.Issues.AddRange(CheckExternalDependenciesAsync().GetAwaiter().GetResult()); return result; } private async Task<List<DiagnosticIssue>> CheckConfigurationSourcesAsync() { var issues = new List<DiagnosticIssue>(); // Check if appsettings files exist var expectedFiles = new[] { "appsettings.json", $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json" }; foreach (var file in expectedFiles) { if (!File.Exists(file)) { issues.Add(new DiagnosticIssue { Level = DiagnosticLevel.Warning, Category = "Configuration Files", Message = $"Configuration file '{file}' not found", Details = "This file is optional but recommended for environment-specific settings" }); } } // Check environment variables var requiredEnvVars = new[] { "ASPNETCORE_ENVIRONMENT" }; foreach (var envVar in requiredEnvVars) { if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envVar))) { issues.Add(new DiagnosticIssue { Level = DiagnosticLevel.Warning, Category = "Environment Variables", Message = $"Environment variable '{envVar}' is not set", Details = "Defaulting to 'Production' environment" }); } } return issues; } private List<DiagnosticIssue> CheckRequiredSettings() { var issues = new List<DiagnosticIssue>(); var requiredSettings = new[] { "ConnectionStrings:DefaultConnection", "Security:Jwt:SecretKey", "Security:Jwt:Issuer", "Security:Jwt:Audience" }; foreach (var setting in requiredSettings) { var value = _configuration[setting]; if (string.IsNullOrEmpty(value)) { issues.Add(new DiagnosticIssue { Level = DiagnosticLevel.Error, Category = "Required Settings", Message = $"Required configuration setting '{setting}' is missing or empty", Details = "This will cause application startup to fail" }); } } return issues; } private List<DiagnosticIssue> CheckConfigurationValues() { var issues = new List<DiagnosticIssue>(); // Check numeric values var dbTimeout = _configuration.GetValue<int>("Database:Timeout", 0); if (dbTimeout <= 0) { issues.Add(new DiagnosticIssue { Level = DiagnosticLevel.Warning, Category = "Configuration Values", Message = "Database timeout is not set or invalid", Details = "Using default timeout of 30 seconds" }); } // Check URL formats var paymentUrl = _configuration["PaymentGateway:BaseUrl"]; if (!string.IsNullOrEmpty(paymentUrl) && !Uri.IsWellFormedUriString(paymentUrl, UriKind.Absolute)) { issues.Add(new DiagnosticIssue { Level = DiagnosticLevel.Error, Category = "Configuration Values", Message = "Payment gateway URL is not a valid URI", Details = "This will cause payment operations to fail" }); } return issues; } private async Task<List<DiagnosticIssue>> CheckExternalDependenciesAsync() { var issues = new List<DiagnosticIssue>(); // Check database connectivity var connectionString = _configuration.GetConnectionString("DefaultConnection"); if (!string.IsNullOrEmpty(connectionString)) { try { await using var connection = new SqlConnection(connectionString); await connection.OpenAsync(); await connection.CloseAsync(); } catch (Exception ex) { issues.Add(new DiagnosticIssue { Level = DiagnosticLevel.Error, Category = "External Dependencies", Message = "Cannot connect to database", Details = $"Database connection failed: {ex.Message}" }); } } return issues; } } public class ConfigurationDiagnosticResult { public List<DiagnosticIssue> Issues { get; set; } = new List<DiagnosticIssue>(); public DateTime DiagnosedAt { get; set; } = DateTime.UtcNow; public bool HasErrors => Issues.Any(i => i.Level == DiagnosticLevel.Error); } public class DiagnosticIssue { public DiagnosticLevel Level { get; set; } public string Category { get; set; } public string Message { get; set; } public string Details { get; set; } } public enum DiagnosticLevel { Information, Warning, Error } // Configuration debugging middleware public class ConfigurationDebugMiddleware { private readonly RequestDelegate _next; private readonly IConfiguration _configuration; private readonly ILogger<ConfigurationDebugMiddleware> _logger; public ConfigurationDebugMiddleware( RequestDelegate next, IConfiguration configuration, ILogger<ConfigurationDebugMiddleware> logger) { _next = next; _configuration = configuration; _logger = logger; } public async Task InvokeAsync(HttpContext context) { // Only enable in development if (context.Request.Query.ContainsKey("debug-config")) { await WriteConfigurationDebugInfo(context); return; } await _next(context); } private async Task WriteConfigurationDebugInfo(HttpContext context) { context.Response.ContentType = "application/json"; var debugInfo = new { Environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"), ConfigurationSources = GetConfigurationSources(), AllSettings = GetAllConfigurationValues(), EnvironmentVariables = GetRelevantEnvironmentVariables() }; var json = System.Text.Json.JsonSerializer.Serialize(debugInfo, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }); await context.Response.WriteAsync(json); } private List<string> GetConfigurationSources() { // This would need reflection to access internal configuration providers return new List<string> { "appsettings.json", $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", "Environment Variables", "Command Line Arguments", "User Secrets (Development only)" }; } private Dictionary<string, string> GetAllConfigurationValues() { var values = new Dictionary<string, string>(); // Get all configuration values (be careful with secrets!) foreach (var (key, value) in _configuration.AsEnumerable()) { if (!string.IsNullOrEmpty(key) && !IsSensitiveKey(key)) { values[key] = value; } } return values; } private Dictionary<string, string> GetRelevantEnvironmentVariables() { var envVars = new Dictionary<string, string>(); var relevantVars = Environment.GetEnvironmentVariables() .Cast<System.Collections.DictionaryEntry>() .Where(e => e.Key.ToString().StartsWith("ASPNETCORE_") || e.Key.ToString().StartsWith("TECHMART_")) .ToDictionary(e => e.Key.ToString(), e => e.Value.ToString()); return relevantVars; } private bool IsSensitiveKey(string key) { var sensitiveKeywords = new[] { "password", "pwd", "secret", "key", "token", "connectionstring" }; return sensitiveKeywords.Any(keyword => key.Contains(keyword, StringComparison.OrdinalIgnoreCase)); } }
15. Real-World Implementation Examples <a name="real-world"></a>
Enterprise-Grade Configuration Setup
// Complete enterprise configuration setup public class EnterpriseConfigurationBuilder { public IHostBuilder CreateEnterpriseHostBuilder(string[] args, string applicationName) { return Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { var env = context.HostingEnvironment; ConfigureEnterpriseAppSettings(config, env); ConfigureEnterpriseSecrets(config, env, applicationName); ConfigureEnterpriseExternalSources(config, env, applicationName); ConfigureEnterpriseMonitoring(config); }) .ConfigureLogging((context, logging) => { logging.AddConfiguration(context.Configuration.GetSection("Logging")); logging.AddConsole(); logging.AddDebug(); logging.AddApplicationInsights(); }) .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); options.ValidateOnBuild = true; }); } private void ConfigureEnterpriseAppSettings(IConfigurationBuilder config, IHostEnvironment env) { // Base configuration config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); // Environment-specific configuration config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); // Environment-specific machine configuration (for overrides) config.AddJsonFile($"appsettings.{env.EnvironmentName}.{Environment.MachineName}.json", optional: true, reloadOnChange: true); } private void ConfigureEnterpriseSecrets(IConfigurationBuilder config, IHostEnvironment env, string applicationName) { if (env.IsDevelopment()) { // User secrets for development config.AddUserSecrets<Program>(); } else { // Cloud secrets for non-development environments var builtConfig = config.Build(); // Azure Key Vault var azureKeyVaultEndpoint = builtConfig["AzureKeyVault:Endpoint"]; if (!string.IsNullOrEmpty(azureKeyVaultEndpoint)) { config.AddAzureKeyVault( new Uri(azureKeyVaultEndpoint), new DefaultAzureCredential()); } // AWS Secrets Manager var awsRegion = builtConfig["AWS:Region"]; var awsSecretName = builtConfig["AWS:Secrets:ApplicationSecretName"]; if (!string.IsNullOrEmpty(awsRegion) && !string.IsNullOrEmpty(awsSecretName)) { config.AddAwsSecretsManager(awsRegion, awsSecretName); } } } private void ConfigureEnterpriseExternalSources(IConfigurationBuilder config, IHostEnvironment env, string applicationName) { var builtConfig = config.Build(); // Database configuration var dbConnectionString = builtConfig.GetConnectionString("ConfigurationDb"); if (!string.IsNullOrEmpty(dbConnectionString)) { config.AddDynamicDatabaseConfiguration( dbConnectionString, env.EnvironmentName, applicationName, reloadOnChange: true, reloadInterval: 60); } // Consul configuration for microservices var consulAddress = builtConfig["Consul:Address"]; if (!string.IsNullOrEmpty(consulAddress)) { config.AddConsulKeyValue(consulAddress, $"{applicationName}/{env.EnvironmentName}"); } } private void ConfigureEnterpriseMonitoring(IConfigurationBuilder config) { // Application Insights config.AddApplicationInsightsSettings(); // Health check configuration config.AddJsonFile("healthchecks.json", optional: true); } } // Real-world startup configuration public class EnterpriseStartup { public EnterpriseStartup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; Environment = env; // Validate configuration on startup ValidateConfiguration(); } public IConfiguration Configuration { get; } public IWebHostEnvironment Environment { get; } private void ValidateConfiguration() { var validator = new EnterpriseConfigurationValidator(Configuration, Environment); var result = validator.Validate(); if (!result.IsValid) { throw new InvalidOperationException( $"Configuration validation failed: {string.Join(", ", result.Errors)}"); } } public void ConfigureServices(IServiceCollection services) { // Configuration validation services.AddSingleton(new EnterpriseConfigurationValidator(Configuration, Environment)); // Strongly-typed configuration services.Configure<EnterpriseAppSettings>(Configuration); services.Configure<DatabaseSettings>(Configuration.GetSection("Database")); services.Configure<SecuritySettings>(Configuration.GetSection("Security")); services.Configure<ExternalServicesSettings>(Configuration.GetSection("ExternalServices")); // Configuration-based service registration ConfigureDatabaseServices(services); ConfigureSecurityServices(services); ConfigureExternalServices(services); ConfigureApplicationServices(services); // Health checks services.AddHealthChecks() .AddSqlServer(Configuration.GetConnectionString("DefaultConnection")) .AddUrlGroup(new Uri(Configuration["ExternalServices:PaymentGateway:HealthCheck"])) .AddApplicationInsightsPublisher(); // Caching ConfigureCaching(services); } private void ConfigureDatabaseServices(IServiceCollection services) { var databaseSettings = Configuration.GetSection("Database").Get<DatabaseSettings>(); services.AddDbContext<ApplicationDbContext>(options => { options.UseSqlServer(databaseSettings.ConnectionString, sqlOptions => { sqlOptions.EnableRetryOnFailure( maxRetryCount: databaseSettings.RetryCount, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); }); if (Environment.IsDevelopment()) { options.EnableSensitiveDataLogging(); options.EnableDetailedErrors(); } }); } private void ConfigureSecurityServices(IServiceCollection services) { var securitySettings = Configuration.GetSection("Security").Get<SecuritySettings>(); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = securitySettings.Jwt.Issuer, ValidAudience = securitySettings.Jwt.Audience, IssuerSigningKey = new SymmetricSecurityKey( Encoding.UTF8.GetBytes(securitySettings.Jwt.SecretKey)) }; }); services.AddAuthorization(options => { options.AddPolicy("AdminOnly", policy => policy.RequireRole("Administrator")); }); } private void ConfigureExternalServices(IServiceCollection services) { var externalServices = Configuration.GetSection("ExternalServices").Get<ExternalServicesSettings>(); // Configure HTTP clients with retry policies services.AddHttpClient<IPaymentService, PaymentService>(client => { client.BaseAddress = new Uri(externalServices.PaymentGateway.BaseUrl); client.DefaultRequestHeaders.Add("X-API-Key", externalServices.PaymentGateway.ApiKey); }) .AddPolicyHandler(GetRetryPolicy()) .AddPolicyHandler(GetCircuitBreakerPolicy()); services.AddHttpClient<IEmailService, EmailService>(client => { client.BaseAddress = new Uri(externalServices.EmailService.BaseUrl); }) .AddPolicyHandler(GetRetryPolicy()); } private void ConfigureApplicationServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Enterprise API", Version = "v1" }); }); // Feature flags var featureSettings = Configuration.GetSection("Features").Get<FeatureSettings>(); if (featureSettings.EnableCaching) { services.AddMemoryCache(); } if (featureSettings.EnableBackgroundServices) { services.AddHostedService<DataSyncService>(); services.AddHostedService<CleanupService>(); } } private void ConfigureCaching(IServiceCollection services) { var cacheSettings = Configuration.GetSection("Cache").Get<CacheSettings>(); if (cacheSettings.Type == "Redis") { services.AddStackExchangeRedisCache(options => { options.Configuration = cacheSettings.RedisConnection; options.InstanceName = cacheSettings.InstanceName; }); } else { services.AddDistributedMemoryCache(); } } private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy() { return HttpPolicyExtensions .HandleTransientHttpError() .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.TooManyRequests) .WaitAndRetryAsync( retryCount: 3, sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), onRetry: (outcome, timespan, retryCount, context) => { // Log retry attempts }); } private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy() { return HttpPolicyExtensions .HandleTransientHttpError() .CircuitBreakerAsync( handledEventsAllowedBeforeBreaking: 3, durationOfBreak: TimeSpan.FromSeconds(30)); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Enterprise API v1")); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHealthChecks("/health"); }); // Configuration diagnostics endpoint (development only) if (env.IsDevelopment()) { app.UseMiddleware<ConfigurationDebugMiddleware>(); } } } // Enterprise configuration classes public class EnterpriseAppSettings { public string ApplicationName { get; set; } public string Version { get; set; } public string Environment { get; set; } public FeatureSettings Features { get; set; } public CacheSettings Cache { get; set; } } public class FeatureSettings { public bool EnableCaching { get; set; } public bool EnableBackgroundServices { get; set; } public bool EnableApiVersioning { get; set; } public bool EnableResponseCompression { get; set; } } public class CacheSettings { public string Type { get; set; } public string RedisConnection { get; set; } public string InstanceName { get; set; } public int DefaultExpiration { get; set; } = 3600; } public class ExternalServicesSettings { public PaymentGatewaySettings PaymentGateway { get; set; } public EmailServiceSettings EmailService { get; set; } public AnalyticsServiceSettings AnalyticsService { get; set; } } public class PaymentGatewaySettings { public string BaseUrl { get; set; } public string ApiKey { get; set; } public string WebhookSecret { get; set; } public string HealthCheck { get; set; } } public class EnterpriseConfigurationValidator { private readonly IConfiguration _configuration; private readonly IWebHostEnvironment _environment; public EnterpriseConfigurationValidator(IConfiguration configuration, IWebHostEnvironment environment) { _configuration = configuration; _environment = environment; } public ValidationResult Validate() { var errors = new List<string>(); // Validate required settings if (string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection"))) { errors.Add("Default database connection string is required"); } // Validate security settings var jwtSecret = _configuration["Security:Jwt:SecretKey"]; if (string.IsNullOrEmpty(jwtSecret) || jwtSecret.Length < 32) { errors.Add("JWT secret key must be at least 32 characters long"); } // Validate external services var paymentUrl = _configuration["ExternalServices:PaymentGateway:BaseUrl"]; if (string.IsNullOrEmpty(paymentUrl)) { errors.Add("Payment gateway base URL is required"); } return new ValidationResult { IsValid = !errors.Any(), Errors = errors }; } } public class ValidationResult { public bool IsValid { get; set; } public List<string> Errors { get; set; } = new List<string>(); }
This comprehensive guide covers ASP.NET Core configuration and secrets management from basic to advanced enterprise-level scenarios. The examples provided demonstrate real-world patterns and best practices that you can adapt for your specific application needs.
Remember to always prioritize security when handling configuration, especially when dealing with secrets and sensitive information. Use secure storage solutions like Azure Key Vault or AWS Secrets Manager in production environments, and never commit secrets to source control.
![ASP.NET Core Configuration and Secrets Mastery: Complete Guide Table of Contents  Introduction to Configuration in ASP.NET Core  Understanding the Configuration System  AppSettings.json Deep Dive  Environment-Specific Configuration  User Secrets for Development  Environment Variables Configuration  Command-Line Configuration  Custom Configuration Providers  Azure Key Vault Integration  AWS Secrets Manager  Database Configuration Provider  Configuration Best Practices  Security Considerations  Troubleshooting Common Issues  Real-World Implementation Examples  1. Introduction to Configuration in ASP.NET Core <a name="introduction"></a> Configuration management is a critical aspect of modern web application development. In ASP.NET Core, the configuration system has been completely redesigned to be more flexible, extensible, and cloud-ready. Let's explore why proper configuration management is essential:  Why Configuration Management Matters Real-Life Scenario: Imagine you're developing an e-commerce application that needs to connect to different databases in development, staging, and production environments. Without proper configuration management, you'd be constantly changing connection strings, risking security breaches and deployment failures.  csharp // Problematic approach - hardcoded configuration public class DatabaseService {     private string _connectionString = "Server=prod-db;Database=Shop;User=admin;Password=secret123";          public void Connect()     {         // This will fail in development and staging!     } } Evolution of Configuration in ASP.NET From Web.config to Modern Approach:  ASP.NET Web Forms: XML-based Web.config with complex sections  ASP.NET MVC: Still Web.config with some improvements  ASP.NET Core: JSON-based, environment-aware, cloud-native  2. Understanding the Configuration System <a name="understanding-system"></a> Configuration Building Blocks The ASP.NET Core configuration system is built around several key concepts:  IConfiguration Interface csharp public interface IConfiguration {     string this[string key] { get; set; }     IConfigurationSection GetSection(string key);     IEnumerable<IConfigurationSection> GetChildren();     IChangeToken GetReloadToken(); } Configuration Sources Hierarchy ASP.NET Core loads configuration from multiple sources in a specific order:  csharp public class Program {     public static void Main(string[] args)     {         CreateHostBuilder(args).Build().Run();     }      public static IHostBuilder CreateHostBuilder(string[] args) =>         Host.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((hostingContext, config) =>             {                 // Configuration sources are loaded in this order:                 // 1. appsettings.json                 // 2. appsettings.{Environment}.json                 // 3. User Secrets (Development environment only)                 // 4. Environment Variables                 // 5. Command-line arguments             })             .ConfigureWebHostDefaults(webBuilder =>             {                 webBuilder.UseStartup<Startup>();             }); } Configuration Providers Deep Dive csharp // Detailed configuration setup with multiple providers public static IHostBuilder CreateHostBuilder(string[] args) =>     Host.CreateDefaultBuilder(args)         .ConfigureAppConfiguration((context, config) =>         {             var env = context.HostingEnvironment;                          // Base appsettings             config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);                          // Environment-specific appsettings             config.AddJsonFile($"appsettings.{env.EnvironmentName}.json",                  optional: true, reloadOnChange: true);                          // User Secrets for development             if (env.IsDevelopment())             {                 config.AddUserSecrets<Program>();             }                          // Environment variables             config.AddEnvironmentVariables();                          // Command-line arguments             if (args != null)             {                 config.AddCommandLine(args);             }                          // Last provider wins - command line has highest priority         }); 3. AppSettings.json Deep Dive <a name="appsettings-json"></a> Structured Configuration with JSON Real-Life Example: E-commerce application configuration  json {   "StoreSettings": {     "StoreName": "TechMart Online",     "MaxProductsPerPage": 50,     "EnableWishlist": true,     "Currency": "USD",     "SupportedCountries": ["US", "CA", "UK", "AU"]   },   "Database": {     "ConnectionString": "Server=localhost;Database=TechMart;Trusted_Connection=true;",     "Timeout": 30,     "RetryCount": 3   },   "PaymentGateway": {     "ApiKey": "pk_test_123456789",     "BaseUrl": "https://api.payments.com/v1",     "WebhookSecret": "whsec_987654321",     "Settings": {       "Timeout": 10000,       "RetryPolicy": "ExponentialBackoff"     }   },   "EmailSettings": {     "SmtpServer": "smtp.techmart.com",     "Port": 587,     "Username": "noreply@techmart.com",     "FromAddress": "noreply@techmart.com",     "Templates": {       "OrderConfirmation": "templates/order-confirmation.html",       "PasswordReset": "templates/password-reset.html"     }   },   "CacheSettings": {     "RedisConnection": "localhost:6379",     "DefaultExpiration": 3600,     "Enabled": true   },   "Security": {     "Jwt": {       "SecretKey": "your-super-secret-key-here",       "Issuer": "TechMart",       "Audience": "TechMartUsers",       "ExpirationMinutes": 60     },     "Cors": {       "AllowedOrigins": ["https://techmart.com", "https://admin.techmart.com"]     }   } } Strongly-Typed Configuration Classes csharp // Configuration classes for strongly-typed access public class StoreSettings {     public string StoreName { get; set; }     public int MaxProductsPerPage { get; set; }     public bool EnableWishlist { get; set; }     public string Currency { get; set; }     public string[] SupportedCountries { get; set; } }  public class DatabaseSettings {     public string ConnectionString { get; set; }     public int Timeout { get; set; }     public int RetryCount { get; set; } }  public class PaymentGatewaySettings {     public string ApiKey { get; set; }     public string BaseUrl { get; set; }     public string WebhookSecret { get; set; }     public PaymentSettings Settings { get; set; } }  public class PaymentSettings {     public int Timeout { get; set; }     public string RetryPolicy { get; set; } }  public class EmailSettings {     public string SmtpServer { get; set; }     public int Port { get; set; }     public string Username { get; set; }     public string FromAddress { get; set; }     public EmailTemplates Templates { get; set; } }  public class EmailTemplates {     public string OrderConfirmation { get; set; }     public string PasswordReset { get; set; } }  public class CacheSettings {     public string RedisConnection { get; set; }     public int DefaultExpiration { get; set; }     public bool Enabled { get; set; } }  public class SecuritySettings {     public JwtSettings Jwt { get; set; }     public CorsSettings Cors { get; set; } }  public class JwtSettings {     public string SecretKey { get; set; }     public string Issuer { get; set; }     public string Audience { get; set; }     public int ExpirationMinutes { get; set; } }  public class CorsSettings {     public string[] AllowedOrigins { get; set; } } Configuration Binding and Validation csharp // Startup configuration with validation public class Startup {     private readonly IConfiguration _configuration;      public Startup(IConfiguration configuration)     {         _configuration = configuration;     }      public void ConfigureServices(IServiceCollection services)     {         // Bind configuration sections to strongly-typed classes         services.Configure<StoreSettings>(_configuration.GetSection("StoreSettings"));         services.Configure<DatabaseSettings>(_configuration.GetSection("Database"));         services.Configure<PaymentGatewaySettings>(_configuration.GetSection("PaymentGateway"));         services.Configure<EmailSettings>(_configuration.GetSection("EmailSettings"));         services.Configure<CacheSettings>(_configuration.GetSection("CacheSettings"));         services.Configure<SecuritySettings>(_configuration.GetSection("Security"));          // Advanced binding with validation         var storeSettings = new StoreSettings();         _configuration.GetSection("StoreSettings").Bind(storeSettings);                  // Validate critical settings         if (string.IsNullOrEmpty(storeSettings.StoreName))         {             throw new InvalidOperationException("StoreName is required in configuration");         }          // Register services that use configuration         services.AddSingleton(storeSettings);                  // Database configuration with validation         var dbSettings = _configuration.GetSection("Database").Get<DatabaseSettings>();         if (string.IsNullOrEmpty(dbSettings?.ConnectionString))         {             throw new InvalidOperationException("Database connection string is required");         }                  services.AddDbContext<ApplicationDbContext>(options =>             options.UseSqlServer(dbSettings.ConnectionString));     } } 4. Environment-Specific Configuration <a name="environment-config"></a> Environment-Based Configuration Strategy Real-Life Scenario: Different configurations for Development, Staging, and Production environments  json // appsettings.Development.json {   "Logging": {     "LogLevel": {       "Default": "Debug",       "Microsoft": "Debug",       "Microsoft.Hosting.Lifetime": "Debug"     }   },   "Database": {     "ConnectionString": "Server=localhost;Database=TechMart_Dev;Trusted_Connection=true;",     "Timeout": 30,     "RetryCount": 3   },   "PaymentGateway": {     "BaseUrl": "https://api.sandbox.payments.com/v1",     "ApiKey": "pk_test_development_key"   },   "Features": {     "EnableSwagger": true,     "EnableDetailedErrors": true,     "UseInMemoryCache": true   } }  // appsettings.Staging.json {   "Logging": {     "LogLevel": {       "Default": "Information",       "Microsoft": "Warning",       "Microsoft.Hosting.Lifetime": "Information"     }   },   "Database": {     "ConnectionString": "Server=staging-db.techmart.com;Database=TechMart_Staging;User Id=appuser;Password=staging_password;",     "Timeout": 30,     "RetryCount": 5   },   "PaymentGateway": {     "BaseUrl": "https://api.staging.payments.com/v1",     "ApiKey": "pk_test_staging_key"   },   "Features": {     "EnableSwagger": false,     "EnableDetailedErrors": true,     "UseInMemoryCache": false   } }  // appsettings.Production.json {   "Logging": {     "LogLevel": {       "Default": "Warning",       "Microsoft": "Warning",       "Microsoft.Hosting.Lifetime": "Warning"     }   },   "Database": {     "ConnectionString": "Server=prod-db.techmart.com;Database=TechMart_Prod;User Id=appuser;Password=production_password;",     "Timeout": 30,     "RetryCount": 5   },   "PaymentGateway": {     "BaseUrl": "https://api.payments.com/v1",     "ApiKey": "pk_live_production_key"   },   "Features": {     "EnableSwagger": false,     "EnableDetailedErrors": false,     "UseInMemoryCache": false   } } Environment Detection and Configuration csharp // Program.cs with environment-specific setup public class Program {     public static void Main(string[] args)     {         CreateHostBuilder(args).Build().Run();     }      public static IHostBuilder CreateHostBuilder(string[] args) =>         Host.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((context, config) =>             {                 var env = context.HostingEnvironment;                                  Console.WriteLine($"Environment: {env.EnvironmentName}");                 Console.WriteLine($"Content Root: {env.ContentRootPath}");                 Console.WriteLine($"Web Root: {env.WebRootPath}");                                  // Load environment-specific configuration                 config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)                       .AddJsonFile($"appsettings.{env.EnvironmentName}.json",                                     optional: true, reloadOnChange: true);                                  // Additional configuration based on environment                 if (env.IsDevelopment())                 {                     // Development-specific configuration                     config.AddUserSecrets<Program>();                 }                 else if (env.IsStaging())                 {                     // Staging-specific configuration                     config.AddJsonFile("appsettings.Staging.Secrets.json",                                        optional: true, reloadOnChange: true);                 }                 else if (env.IsProduction())                 {                     // Production-specific configuration                     // Rely on environment variables and secure vaults                 }             })             .ConfigureWebHostDefaults(webBuilder =>             {                 webBuilder.UseStartup<Startup>();             }); } Environment-Based Service Registration csharp // Environment-specific service configuration public class Startup {     public Startup(IConfiguration configuration, IWebHostEnvironment env)     {         Configuration = configuration;         Environment = env;     }      public IConfiguration Configuration { get; }     public IWebHostEnvironment Environment { get; }      public void ConfigureServices(IServiceCollection services)     {         // Common services for all environments         services.AddControllers();         services.AddHttpClient();                  // Environment-specific services         if (Environment.IsDevelopment())         {             services.AddDatabaseDeveloperPageExceptionFilter();             services.AddSwaggerGen(c =>             {                 c.SwaggerDoc("v1", new OpenApiInfo { Title = "TechMart API", Version = "v1" });             });         }          // Database configuration based on environment         if (Environment.IsDevelopment())         {             services.AddDbContext<ApplicationDbContext>(options =>                 options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))                        .EnableSensitiveDataLogging());         }         else         {             services.AddDbContext<ApplicationDbContext>(options =>                 options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));         }          // Cache configuration         if (Configuration.GetValue<bool>("Features:UseInMemoryCache"))         {             services.AddMemoryCache();         }         else         {             var redisConnection = Configuration.GetValue<string>("CacheSettings:RedisConnection");             services.AddStackExchangeRedisCache(options =>             {                 options.Configuration = redisConnection;             });         }     }      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)     {         if (env.IsDevelopment())         {             app.UseDeveloperExceptionPage();             app.UseSwagger();             app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TechMart API v1"));         }         else         {             app.UseExceptionHandler("/Error");             app.UseHsts();         }          app.UseHttpsRedirection();         app.UseRouting();         app.UseAuthorization();         app.UseEndpoints(endpoints =>         {             endpoints.MapControllers();         });     } } 5. User Secrets for Development <a name="user-secrets"></a> Why Use User Secrets? Real-Life Problem: Developers committing sensitive data to source control  csharp // Before User Secrets - sensitive data in appsettings.json {   "ConnectionStrings": {     "DefaultConnection": "Server=localhost;Database=MyApp;User Id=sa;Password=MySuperSecretPassword123!"   },   "ApiKeys": {     "SendGrid": "SG.abc123def456ghi789",     "Stripe": "sk_test_1234567890abcdef"   } } Setting Up User Secrets Step 1: Initialize User Secrets bash # In the project directory dotnet user-secrets init Step 2: Add Secrets bash # Add connection string dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=localhost;Database=MyApp;User Id=sa;Password=DevPassword123!"  # Add API keys dotnet user-secrets set "ApiKeys:SendGrid" "SG.devkey123456789" dotnet user-secrets set "ApiKeys:Stripe" "sk_test_devkey123456789"  # Add JWT secret dotnet user-secrets set "Security:Jwt:SecretKey" "dev-super-secret-jwt-key-2024" Step 3: secrets.json File Structure json {   "ConnectionStrings:DefaultConnection": "Server=localhost;Database=MyApp_Dev;User Id=sa;Password=DevPassword123!",   "ApiKeys": {     "SendGrid": "SG.devkey123456789",     "Stripe": "sk_test_devkey123456789"   },   "Security:Jwt:SecretKey": "dev-super-secret-jwt-key-2024",   "PaymentGateway": {     "ApiKey": "pk_test_dev_123456789",     "WebhookSecret": "whsec_dev_987654321"   } } Programmatic Access to User Secrets csharp // Advanced User Secrets management public class DevelopmentSecretsManager {     private readonly IConfiguration _configuration;      public DevelopmentSecretsManager(IConfiguration configuration)     {         _configuration = configuration;     }      public void ValidateDevelopmentSecrets()     {         var requiredSecrets = new[]         {             "ConnectionStrings:DefaultConnection",             "ApiKeys:SendGrid",             "Security:Jwt:SecretKey"         };          var missingSecrets = requiredSecrets             .Where(secret => string.IsNullOrEmpty(_configuration[secret]))             .ToList();          if (missingSecrets.Any())         {             throw new InvalidOperationException(                 $"Missing required development secrets: {string.Join(", ", missingSecrets)}. " +                 "Run 'dotnet user-secrets set [key] [value]' to set them.");         }     }      public string GetSecret(string key)     {         var value = _configuration[key];         if (string.IsNullOrEmpty(value))         {             throw new ArgumentException($"Secret '{key}' not found in user secrets");         }         return value;     }      public T GetSecret<T>(string key)     {         var value = GetSecret(key);         return (T)Convert.ChangeType(value, typeof(T));     } }  // Integration in Startup public class Startup {     public Startup(IConfiguration configuration, IWebHostEnvironment env)     {         Configuration = configuration;         Environment = env;     }      public IConfiguration Configuration { get; }     public IWebHostEnvironment Environment { get; }      public void ConfigureServices(IServiceCollection services)     {         // Validate secrets in development         if (Environment.IsDevelopment())         {             var secretsManager = new DevelopmentSecretsManager(Configuration);             secretsManager.ValidateDevelopmentSecrets();         }          // Use secrets in services         var connectionString = Configuration.GetConnectionString("DefaultConnection");         services.AddDbContext<ApplicationDbContext>(options =>             options.UseSqlServer(connectionString));     } } User Secrets Best Practices csharp // Secure development practices public static class SecretsBestPractices {     public static void EnsureSecretsAreNotInAppSettings(IWebHostEnvironment env)     {         if (env.IsDevelopment())         {             var appSettingsPath = Path.Combine(env.ContentRootPath, "appsettings.json");             var appSettingsContent = File.ReadAllText(appSettingsPath);                          var sensitivePatterns = new[]             {                 @"password=([^;""']+)",                 @"pwd=([^;""']+)",                 @"api[_-]?key=([^;""']+)",                 @"secret=([^;""']+)"             };              foreach (var pattern in sensitivePatterns)             {                 var matches = System.Text.RegularExpressions.Regex.Matches(appSettingsContent, pattern,                      System.Text.RegularExpressions.RegexOptions.IgnoreCase);                                  if (matches.Count > 0)                 {                     throw new InvalidOperationException(                         "Sensitive data found in appsettings.json. Move to user secrets.");                 }             }         }     } } 6. Environment Variables Configuration <a name="environment-variables"></a> Environment Variables in Different Environments Real-Life Scenario: Deployment to various environments (Docker, Azure, AWS, Kubernetes)  csharp // Environment variable configuration provider public static class EnvironmentVariablesConfig {     public static void ConfigureEnvironmentVariables(this IConfigurationBuilder config)     {         config.AddEnvironmentVariables();                  // Add prefix for application-specific variables         config.AddEnvironmentVariables("TECHMART_");     } }  // Usage in Program.cs public static IHostBuilder CreateHostBuilder(string[] args) =>     Host.CreateDefaultBuilder(args)         .ConfigureAppConfiguration((context, config) =>         {             config.AddJsonFile("appsettings.json", optional: false)                   .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json",                                optional: true)                   .AddEnvironmentVariables("TECHMART_") // Application-specific                   .AddEnvironmentVariables(); // All environment variables         }); Environment Variable Naming Conventions csharp // Environment variable mapping examples public static class EnvVarConstants {     // Database     public const string DB_CONNECTION = "TECHMART_DB_CONNECTION";     public const string DB_TIMEOUT = "TECHMART_DB_TIMEOUT";          // API Keys     public const string SENDGRID_API_KEY = "TECHMART_SENDGRID_API_KEY";     public const string STRIPE_API_KEY = "TECHMART_STRIPE_API_KEY";          // Application Settings     public const string ENVIRONMENT = "ASPNETCORE_ENVIRONMENT";     public const string URLs = "ASPNETCORE_URLS";          // Feature Flags     public const string FEATURE_SWAGGER = "TECHMART_FEATURE_SWAGGER";     public const string FEATURE_CACHE = "TECHMART_FEATURE_CACHE"; }  // Environment variable helper class public class EnvironmentConfig {     private readonly IConfiguration _configuration;      public EnvironmentConfig(IConfiguration configuration)     {         _configuration = configuration;     }      public string DatabaseConnection =>          GetRequiredValue(EnvVarConstants.DB_CONNECTION);      public string SendGridApiKey =>          GetRequiredValue(EnvVarConstants.SENDGRID_API_KEY);      public bool EnableSwagger =>          GetValue(EnvVarConstants.FEATURE_SWAGGER, false);      public int DatabaseTimeout =>          GetValue(EnvVarConstants.DB_TIMEOUT, 30);      private string GetRequiredValue(string key)     {         var value = _configuration[key];         if (string.IsNullOrEmpty(value))         {             throw new InvalidOperationException($"Required environment variable '{key}' is missing");         }         return value;     }      private T GetValue<T>(string key, T defaultValue)     {         var value = _configuration[key];         if (string.IsNullOrEmpty(value))         {             return defaultValue;         }          try         {             return (T)Convert.ChangeType(value, typeof(T));         }         catch (Exception ex)         {             throw new InvalidOperationException(                 $"Unable to convert environment variable '{key}' value '{value}' to type {typeof(T).Name}", ex);         }     } } Docker and Container Configuration dockerfile # Dockerfile with environment variables FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443  FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["TechMart.Web/TechMart.Web.csproj", "TechMart.Web/"] RUN dotnet restore "TechMart.Web/TechMart.Web.csproj" COPY . . WORKDIR "/src/TechMart.Web" RUN dotnet build "TechMart.Web.csproj" -c Release -o /app/build  FROM build AS publish RUN dotnet publish "TechMart.Web.csproj" -c Release -o /app/publish  FROM base AS final WORKDIR /app COPY --from=publish /app/publish .  # Environment variables for container ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:80 ENV TECHMART_DB_TIMEOUT=30 ENV TECHMART_FEATURE_SWAGGER=false  ENTRYPOINT ["dotnet", "TechMart.Web.dll"] yaml # docker-compose.yml with environment variables version: '3.8'  services:   techmart.web:     image: techmart/web:latest     build:       context: .       dockerfile: TechMart.Web/Dockerfile     environment:       - ASPNETCORE_ENVIRONMENT=Development       - TECHMART_DB_CONNECTION=Server=techmart.db;Database=TechMart_Dev;User Id=sa;Password=DevPassword123!       - TECHMART_SENDGRID_API_KEY=SG.docker_dev_key       - TECHMART_STRIPE_API_KEY=sk_test_docker_key       - TECHMART_FEATURE_SWAGGER=true     ports:       - "5000:80"     depends_on:       - techmart.db    techmart.db:     image: mcr.microsoft.com/mssql/server:2019-latest     environment:       - SA_PASSWORD=DevPassword123!       - ACCEPT_EULA=Y     ports:       - "1433:1433" 7. Command-Line Configuration <a name="command-line"></a> Command-Line Arguments in ASP.NET Core Real-Life Scenario: Overriding configuration for specific deployments or debugging  csharp // Command-line configuration setup public class Program {     public static void Main(string[] args)     {         CreateHostBuilder(args).Build().Run();     }      public static IHostBuilder CreateHostBuilder(string[] args) =>         Host.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((context, config) =>             {                 // Configure command-line arguments with custom mappings                 var switchMappings = new Dictionary<string, string>                 {                     { "--urls", "urls" },                     { "--environment", "environment" },                     { "--db-connection", "ConnectionStrings:DefaultConnection" },                     { "--enable-swagger", "Features:EnableSwagger" },                     { "--cache-timeout", "CacheSettings:DefaultExpiration" },                     { "--log-level", "Logging:LogLevel:Default" }                 };                  config.AddCommandLine(args, switchMappings);             })             .ConfigureWebHostDefaults(webBuilder =>             {                 webBuilder.UseStartup<Startup>();             }); } Advanced Command-Line Processing csharp // Custom command-line argument processor public class CommandLineConfig {     private readonly string[] _args;      public CommandLineConfig(string[] args)     {         _args = args;     }      public Dictionary<string, string> ParseArguments()     {         var config = new Dictionary<string, string>();                  for (int i = 0; i < _args.Length; i++)         {             var arg = _args[i];                          if (arg.StartsWith("--"))             {                 var key = arg.Substring(2);                 string value = "true"; // Default for flags                  // Check if next argument is a value (not another flag)                 if (i + 1 < _args.Length && !_args[i + 1].StartsWith("--"))                 {                     value = _args[i + 1];                     i++; // Skip the value in next iteration                 }                  config[key] = value;             }             else if (arg.StartsWith("/"))             {                 // Windows-style arguments: /key value or /key:value                 var parts = arg.Substring(1).Split(':');                 var key = parts[0];                 var value = parts.Length > 1 ? parts[1] : "true";                  config[key] = value;             }             else if (arg.Contains("="))             {                 // Key=value format                 var parts = arg.Split('=');                 if (parts.Length == 2)                 {                     config[parts[0]] = parts[1];                 }             }         }          return config;     }      public void ValidateRequiredArguments(Dictionary<string, string> arguments)     {         var requiredArgs = new[] { "db-connection", "environment" };         var missingArgs = requiredArgs.Where(arg => !arguments.ContainsKey(arg)).ToList();          if (missingArgs.Any())         {             throw new ArgumentException(                 $"Missing required command-line arguments: {string.Join(", ", missingArgs)}");         }     } }  // Integration with configuration public static class CommandLineConfigExtensions {     public static IConfigurationBuilder AddCustomCommandLine(         this IConfigurationBuilder builder,          string[] args)     {         var commandLineConfig = new CommandLineConfig(args);         var arguments = commandLineConfig.ParseArguments();                  // Validate required arguments         commandLineConfig.ValidateRequiredArguments(arguments);                  // Add to configuration         foreach (var (key, value) in arguments)         {             Environment.SetEnvironmentVariable($"CMDLINE_{key}", value);         }          return builder.AddInMemoryCollection(arguments);     } } Real-World Command-Line Usage Examples bash # Development with specific settings dotnet run --urls "https://localhost:5001" --environment "Development" --db-connection "Server=localhost;Database=DevDB;Trusted_Connection=true" --enable-swagger true --log-level "Debug"  # Production with minimal logging dotnet run --urls "http://*:80" --environment "Production" --db-connection "Server=prod-db;Database=ProdDB;User Id=appuser;Password=ProdPass123!" --enable-swagger false --log-level "Warning"  # Docker container with environment overrides docker run -p 8080:80 techmart/app --db-connection "Server=sql-server;Database=AppDB;User Id=sa;Password=DockerPass123!" --cache-timeout 3600 8. Custom Configuration Providers <a name="custom-providers"></a> Building Custom Configuration Providers Real-Life Scenario: Reading configuration from a custom XML file or external service  csharp // Custom XML configuration provider public class XmlConfigurationProvider : ConfigurationProvider {     private readonly string _filePath;      public XmlConfigurationProvider(string filePath)     {         _filePath = filePath;     }      public override void Load()     {         var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);                  try         {             if (File.Exists(_filePath))             {                 var doc = XDocument.Load(_filePath);                 ParseXmlElement(doc.Root, "", data);             }         }         catch (Exception ex)         {             throw new InvalidOperationException($"Failed to load XML configuration from {_filePath}", ex);         }          Data = data;     }      private void ParseXmlElement(XElement element, string prefix, Dictionary<string, string> data)     {         foreach (var child in element.Elements())         {             var currentKey = string.IsNullOrEmpty(prefix)                  ? child.Name.LocalName                  : $"{prefix}:{child.Name.LocalName}";              if (child.HasElements)             {                 ParseXmlElement(child, currentKey, data);             }             else             {                 data[currentKey] = child.Value;             }         }     } }  public class XmlConfigurationSource : IConfigurationSource {     public string FilePath { get; set; }      public IConfigurationProvider Build(IConfigurationBuilder builder)     {         return new XmlConfigurationProvider(FilePath);     } }  public static class XmlConfigurationExtensions {     public static IConfigurationBuilder AddXmlFile(         this IConfigurationBuilder builder,          string path,          bool optional = false)     {         if (builder == null)         {             throw new ArgumentNullException(nameof(builder));         }          if (string.IsNullOrEmpty(path))         {             throw new ArgumentException("File path must not be null or empty", nameof(path));         }          var source = new XmlConfigurationSource         {             FilePath = path,             Optional = optional         };          builder.Add(source);         return builder;     } } Database Configuration Provider csharp // Database configuration provider for dynamic configuration public class DatabaseConfigurationProvider : ConfigurationProvider, IDisposable {     private readonly DatabaseConfigurationSource _source;     private readonly Timer _refreshTimer;     private bool _disposed = false;      public DatabaseConfigurationProvider(DatabaseConfigurationSource source)     {         _source = source;                  if (_source.ReloadOnChange && _source.ReloadInterval > 0)         {             _refreshTimer = new Timer(RefreshConfiguration, null,                  TimeSpan.FromSeconds(_source.ReloadInterval),                  TimeSpan.FromSeconds(_source.ReloadInterval));         }     }      public override void Load()     {         RefreshConfiguration();     }      private void RefreshConfiguration(object state = null)     {         try         {             var newData = LoadConfigurationFromDatabase();                          // Only update if configuration changed             if (!Data.SequenceEqual(newData))             {                 Data = newData;                 OnReload(); // Notify about configuration changes             }         }         catch (Exception ex)         {             // Log error but don't crash the application             Console.WriteLine($"Failed to refresh configuration from database: {ex.Message}");         }     }      private Dictionary<string, string> LoadConfigurationFromDatabase()     {         var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);                  using var connection = new SqlConnection(_source.ConnectionString);         connection.Open();                  var command = new SqlCommand(             "SELECT [Key], [Value], [Environment] FROM Configuration WHERE [Environment] = @Environment OR [Environment] IS NULL",              connection);                  command.Parameters.AddWithValue("@Environment", _source.Environment);                  using var reader = command.ExecuteReader();         while (reader.Read())         {             var key = reader.GetString(0);             var value = reader.GetString(1);             data[key] = value;         }                  return data;     }      public void Dispose()     {         if (!_disposed)         {             _refreshTimer?.Dispose();             _disposed = true;         }     } }  public class DatabaseConfigurationSource : IConfigurationSource {     public string ConnectionString { get; set; }     public string Environment { get; set; }     public bool ReloadOnChange { get; set; }     public int ReloadInterval { get; set; } = 30; // seconds      public IConfigurationProvider Build(IConfigurationBuilder builder)     {         return new DatabaseConfigurationProvider(this);     } }  public static class DatabaseConfigurationExtensions {     public static IConfigurationBuilder AddDatabaseConfiguration(         this IConfigurationBuilder builder,         string connectionString,         string environment,         bool reloadOnChange = false,         int reloadInterval = 30)     {         return builder.Add(new DatabaseConfigurationSource         {             ConnectionString = connectionString,             Environment = environment,             ReloadOnChange = reloadOnChange,             ReloadInterval = reloadInterval         });     } } 9. Azure Key Vault Integration <a name="azure-key-vault"></a> Securing Secrets with Azure Key Vault Real-Life Scenario: Enterprise application with multiple environments and compliance requirements  csharp // Azure Key Vault configuration provider public class Program {     public static async Task Main(string[] args)     {         var host = CreateHostBuilder(args).Build();                  // Validate Key Vault connectivity         await ValidateKeyVaultConnection(host.Services);                  await host.RunAsync();     }      public static IHostBuilder CreateHostBuilder(string[] args) =>         Host.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((context, config) =>             {                 var builtConfig = config.Build();                                  // Add Azure Key Vault                 var keyVaultEndpoint = builtConfig["AzureKeyVault:Endpoint"];                 if (!string.IsNullOrEmpty(keyVaultEndpoint))                 {                     var azureServiceTokenProvider = new AzureServiceTokenProvider();                     var keyVaultClient = new KeyVaultClient(                         new KeyVaultClient.AuthenticationCallback(                             azureServiceTokenProvider.KeyVaultTokenCallback));                                          config.AddAzureKeyVault(                         keyVaultEndpoint,                         keyVaultClient,                         new DefaultKeyVaultSecretManager());                 }             })             .ConfigureWebHostDefaults(webBuilder =>             {                 webBuilder.UseStartup<Startup>();             });      private static async Task ValidateKeyVaultConnection(IServiceProvider services)     {         try         {             var configuration = services.GetRequiredService<IConfiguration>();             var keyVaultEndpoint = configuration["AzureKeyVault:Endpoint"];                          if (!string.IsNullOrEmpty(keyVaultEndpoint))             {                 var secretClient = new SecretClient(new Uri(keyVaultEndpoint),                      new DefaultAzureCredential());                                  // Test connection by trying to list secrets                 await secretClient.GetPropertiesOfSecretsAsync().FirstAsync();                                  Console.WriteLine("✅ Azure Key Vault connection successful");             }         }         catch (Exception ex)         {             Console.WriteLine($"❌ Azure Key Vault connection failed: {ex.Message}");             throw;         }     } } Advanced Key Vault Management csharp // Key Vault secret management service public class KeyVaultSecretManager {     private readonly SecretClient _secretClient;     private readonly ILogger<KeyVaultSecretManager> _logger;      public KeyVaultSecretManager(IConfiguration configuration, ILogger<KeyVaultSecretManager> logger)     {         var keyVaultEndpoint = configuration["AzureKeyVault:Endpoint"];         if (string.IsNullOrEmpty(keyVaultEndpoint))         {             throw new InvalidOperationException("Azure Key Vault endpoint is not configured");         }          _secretClient = new SecretClient(new Uri(keyVaultEndpoint), new DefaultAzureCredential());         _logger = logger;     }      public async Task<string> GetSecretAsync(string secretName)     {         try         {             var secret = await _secretClient.GetSecretAsync(secretName);             return secret.Value.Value;         }         catch (RequestFailedException ex) when (ex.Status == 404)         {             _logger.LogWarning("Secret '{SecretName}' not found in Key Vault", secretName);             return null;         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to retrieve secret '{SecretName}' from Key Vault", secretName);             throw;         }     }      public async Task SetSecretAsync(string secretName, string secretValue)     {         try         {             await _secretClient.SetSecretAsync(secretName, secretValue);             _logger.LogInformation("Secret '{SecretName}' updated in Key Vault", secretName);         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to set secret '{SecretName}' in Key Vault", secretName);             throw;         }     }      public async Task<IEnumerable<string>> ListSecretsAsync()     {         var secrets = new List<string>();                  await foreach (var secretProperties in _secretClient.GetPropertiesOfSecretsAsync())         {             secrets.Add(secretProperties.Name);         }                  return secrets;     }      public async Task<bool> SecretExistsAsync(string secretName)     {         try         {             await _secretClient.GetSecretAsync(secretName);             return true;         }         catch (RequestFailedException ex) when (ex.Status == 404)         {             return false;         }     } }  // Startup configuration for Key Vault public class Startup {     public Startup(IConfiguration configuration, IWebHostEnvironment env)     {         Configuration = configuration;         Environment = env;     }      public IConfiguration Configuration { get; }     public IWebHostEnvironment Environment { get; }      public void ConfigureServices(IServiceCollection services)     {         // Register Key Vault service         services.AddSingleton<KeyVaultSecretManager>();                  // Configure database using Key Vault         services.AddDbContext<ApplicationDbContext>(options =>         {             var connectionString = Configuration.GetConnectionString("DefaultConnection");             options.UseSqlServer(connectionString);         });          // Configure other services with secrets from Key Vault         services.Configure<PaymentGatewaySettings>(options =>         {             options.ApiKey = Configuration["PaymentGateway--ApiKey"];             options.WebhookSecret = Configuration["PaymentGateway--WebhookSecret"];         });     } } Key Vault Secret Rotation csharp // Secret rotation service public class SecretRotationService : BackgroundService {     private readonly KeyVaultSecretManager _secretManager;     private readonly IConfiguration _configuration;     private readonly ILogger<SecretRotationService> _logger;      public SecretRotationService(         KeyVaultSecretManager secretManager,         IConfiguration configuration,         ILogger<SecretRotationService> logger)     {         _secretManager = secretManager;         _configuration = configuration;         _logger = logger;     }      protected override async Task ExecuteAsync(CancellationToken stoppingToken)     {         while (!stoppingToken.IsCancellationRequested)         {             try             {                 await RotateSecretsIfNeeded();                 await Task.Delay(TimeSpan.FromHours(24), stoppingToken); // Check daily             }             catch (Exception ex)             {                 _logger.LogError(ex, "Secret rotation failed");                 await Task.Delay(TimeSpan.FromHours(1), stoppingToken); // Retry after 1 hour             }         }     }      private async Task RotateSecretsIfNeeded()     {         var secretsToRotate = new[] { "DatabasePassword", "ApiKey--Primary", "JwtSecret" };                  foreach (var secretName in secretsToRotate)         {             if (await ShouldRotateSecret(secretName))             {                 await RotateSecret(secretName);             }         }     }      private async Task<bool> ShouldRotateSecret(string secretName)     {         // Check secret age or other rotation criteria         var secret = await _secretManager.GetSecretAsync(secretName);         if (secret == null) return false;          // Implement rotation logic based on your requirements         return false; // Placeholder     }      private async Task RotateSecret(string secretName)     {         _logger.LogInformation("Rotating secret: {SecretName}", secretName);                  // Generate new secret value         var newSecretValue = GenerateNewSecret(secretName);                  // Set new version in Key Vault         await _secretManager.SetSecretAsync(secretName, newSecretValue);                  _logger.LogInformation("Successfully rotated secret: {SecretName}", secretName);     }      private string GenerateNewSecret(string secretName)     {         return secretName switch         {             "DatabasePassword" => GenerateSecurePassword(),             "ApiKey--Primary" => GenerateApiKey(),             "JwtSecret" => GenerateJwtSecret(),             _ => Guid.NewGuid().ToString()         };     }      private string GenerateSecurePassword()     {         const string validChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*";         var random = new Random();         return new string(Enumerable.Repeat(validChars, 32)             .Select(s => s[random.Next(s.Length)]).ToArray());     }      private string GenerateApiKey() => $"key_{Guid.NewGuid():N}";     private string GenerateJwtSecret() => Convert.ToBase64String(Guid.NewGuid().ToByteArray()); } 10. AWS Secrets Manager <a name="aws-secrets"></a> AWS Secrets Manager Integration Real-Life Scenario: Multi-cloud deployment with AWS infrastructure  csharp // AWS Secrets Manager configuration provider public class AwsSecretsManagerConfigurationProvider : ConfigurationProvider {     private readonly string _region;     private readonly string _secretName;     private readonly IAmazonSecretsManager _secretsClient;      public AwsSecretsManagerConfigurationProvider(string region, string secretName)     {         _region = region;         _secretName = secretName;         _secretsClient = new AmazonSecretsManagerClient(RegionEndpoint.GetBySystemName(region));     }      public override void Load()     {         try         {             var secret = GetSecretValueAsync().GetAwaiter().GetResult();             var data = ParseSecretString(secret);             Data = data;         }         catch (Exception ex)         {             throw new InvalidOperationException($"Failed to load secrets from AWS Secrets Manager: {ex.Message}", ex);         }     }      private async Task<string> GetSecretValueAsync()     {         var request = new GetSecretValueRequest         {             SecretId = _secretName         };          var response = await _secretsClient.GetSecretValueAsync(request);         return response.SecretString;     }      private Dictionary<string, string> ParseSecretString(string secretString)     {         var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);                  try         {             var json = JsonDocument.Parse(secretString);             ParseJsonElement(json.RootElement, "", data);         }         catch (JsonException)         {             // If not JSON, treat as simple key-value pairs             data[_secretName] = secretString;         }                  return data;     }      private void ParseJsonElement(JsonElement element, string prefix, Dictionary<string, string> data)     {         switch (element.ValueKind)         {             case JsonValueKind.Object:                 foreach (var property in element.EnumerateObject())                 {                     var currentKey = string.IsNullOrEmpty(prefix)                          ? property.Name                          : $"{prefix}:{property.Name}";                     ParseJsonElement(property.Value, currentKey, data);                 }                 break;                              case JsonValueKind.Array:                 var index = 0;                 foreach (var item in element.EnumerateArray())                 {                     var currentKey = $"{prefix}:{index}";                     ParseJsonElement(item, currentKey, data);                     index++;                 }                 break;                              default:                 data[prefix] = element.ToString();                 break;         }     } }  public class AwsSecretsManagerConfigurationSource : IConfigurationSource {     public string Region { get; set; }     public string SecretName { get; set; }      public IConfigurationProvider Build(IConfigurationBuilder builder)     {         return new AwsSecretsManagerConfigurationProvider(Region, SecretName);     } }  public static class AwsSecretsManagerConfigurationExtensions {     public static IConfigurationBuilder AddAwsSecretsManager(         this IConfigurationBuilder builder,         string region,         string secretName)     {         return builder.Add(new AwsSecretsManagerConfigurationSource         {             Region = region,             SecretName = secretName         });     } } Multi-Cloud Secret Management csharp // Unified secret management service public interface ISecretManager {     Task<string> GetSecretAsync(string secretName);     Task SetSecretAsync(string secretName, string secretValue);     Task<bool> SecretExistsAsync(string secretName); }  public class MultiCloudSecretManager : ISecretManager {     private readonly KeyVaultSecretManager _azureSecretManager;     private readonly AwsSecretManager _awsSecretManager;     private readonly IConfiguration _configuration;     private readonly ILogger<MultiCloudSecretManager> _logger;      public MultiCloudSecretManager(         KeyVaultSecretManager azureSecretManager,         AwsSecretManager awsSecretManager,         IConfiguration configuration,         ILogger<MultiCloudSecretManager> logger)     {         _azureSecretManager = azureSecretManager;         _awsSecretManager = awsSecretManager;         _configuration = configuration;         _logger = logger;     }      public async Task<string> GetSecretAsync(string secretName)     {         // Determine which cloud provider to use based on configuration         var cloudProvider = _configuration["CloudProvider"] ?? "Azure";                  try         {             return cloudProvider switch             {                 "Azure" => await _azureSecretManager.GetSecretAsync(secretName),                 "AWS" => await _awsSecretManager.GetSecretAsync(secretName),                 _ => throw new InvalidOperationException($"Unsupported cloud provider: {cloudProvider}")             };         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to retrieve secret '{SecretName}' from {CloudProvider}",                  secretName, cloudProvider);             throw;         }     }      public async Task SetSecretAsync(string secretName, string secretValue)     {         var cloudProvider = _configuration["CloudProvider"] ?? "Azure";                  try         {             switch (cloudProvider)             {                 case "Azure":                     await _azureSecretManager.SetSecretAsync(secretName, secretValue);                     break;                 case "AWS":                     await _awsSecretManager.SetSecretAsync(secretName, secretValue);                     break;                 default:                     throw new InvalidOperationException($"Unsupported cloud provider: {cloudProvider}");             }                          _logger.LogInformation("Secret '{SecretName}' updated in {CloudProvider}",                  secretName, cloudProvider);         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to set secret '{SecretName}' in {CloudProvider}",                  secretName, cloudProvider);             throw;         }     }      public async Task<bool> SecretExistsAsync(string secretName)     {         var cloudProvider = _configuration["CloudProvider"] ?? "Azure";                  return cloudProvider switch         {             "Azure" => await _azureSecretManager.SecretExistsAsync(secretName),             "AWS" => await _awsSecretManager.SecretExistsAsync(secretName),             _ => throw new InvalidOperationException($"Unsupported cloud provider: {cloudProvider}")         };     } }  // AWS Secret Manager implementation public class AwsSecretManager {     private readonly IAmazonSecretsManager _secretsClient;     private readonly ILogger<AwsSecretManager> _logger;      public AwsSecretManager(string region, ILogger<AwsSecretManager> logger)     {         _secretsClient = new AmazonSecretsManagerClient(RegionEndpoint.GetBySystemName(region));         _logger = logger;     }      public async Task<string> GetSecretAsync(string secretName)     {         try         {             var request = new GetSecretValueRequest { SecretId = secretName };             var response = await _secretsClient.GetSecretValueAsync(request);             return response.SecretString;         }         catch (ResourceNotFoundException)         {             _logger.LogWarning("Secret '{SecretName}' not found in AWS Secrets Manager", secretName);             return null;         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to retrieve secret '{SecretName}' from AWS Secrets Manager", secretName);             throw;         }     }      public async Task SetSecretAsync(string secretName, string secretValue)     {         try         {             var request = new PutSecretValueRequest             {                 SecretId = secretName,                 SecretString = secretValue             };                          await _secretsClient.PutSecretValueAsync(request);         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to set secret '{SecretName}' in AWS Secrets Manager", secretName);             throw;         }     }      public async Task<bool> SecretExistsAsync(string secretName)     {         try         {             await GetSecretAsync(secretName);             return true;         }         catch (ResourceNotFoundException)         {             return false;         }     } } 11. Database Configuration Provider <a name="database-provider"></a> Dynamic Database Configuration Real-Life Scenario: Application that needs runtime configuration changes without redeployment  csharp // Advanced database configuration provider public class DynamicDatabaseConfigurationProvider : ConfigurationProvider, IDisposable {     private readonly DynamicDatabaseConfigurationSource _source;     private readonly Timer _refreshTimer;     private readonly ILogger<DynamicDatabaseConfigurationProvider> _logger;     private bool _disposed = false;      public DynamicDatabaseConfigurationProvider(DynamicDatabaseConfigurationSource source)     {         _source = source;         _logger = source.LoggerFactory?.CreateLogger<DynamicDatabaseConfigurationProvider>();          if (_source.ReloadOnChange)         {             _refreshTimer = new Timer(async _ => await RefreshConfigurationAsync(),                  null,                  TimeSpan.FromSeconds(_source.ReloadInterval),                  TimeSpan.FromSeconds(_source.ReloadInterval));         }     }      public override void Load()     {         LoadAsync().GetAwaiter().GetResult();     }      private async Task LoadAsync()     {         try         {             await RefreshConfigurationAsync();         }         catch (Exception ex)         {             _logger?.LogError(ex, "Failed to load configuration from database");             throw;         }     }      private async Task RefreshConfigurationAsync()     {         try         {             var newData = await LoadConfigurationFromDatabaseAsync();                          if (!Data.SequenceEqual(newData))             {                 Data = newData;                 OnReload();                 _logger?.LogInformation("Configuration reloaded from database");             }         }         catch (Exception ex)         {             _logger?.LogError(ex, "Failed to refresh configuration from database");         }     }      private async Task<Dictionary<string, string>> LoadConfigurationFromDatabaseAsync()     {         var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);                  await using var connection = new SqlConnection(_source.ConnectionString);         await connection.OpenAsync();                  var command = new SqlCommand(_source.Query, connection);         command.Parameters.AddWithValue("@Environment", _source.Environment);         command.Parameters.AddWithValue("@Application", _source.ApplicationName);                  await using var reader = await command.ExecuteReaderAsync();         while (await reader.ReadAsync())         {             var key = reader.GetString(0);             var value = reader.IsDBNull(1) ? null : reader.GetString(1);             data[key] = value;         }                  return data;     }      public void Dispose()     {         if (!_disposed)         {             _refreshTimer?.Dispose();             _disposed = true;         }     } }  public class DynamicDatabaseConfigurationSource : IConfigurationSource {     public string ConnectionString { get; set; }     public string Query { get; set; } =          "SELECT [Key], [Value] FROM Configuration WHERE ([Environment] = @Environment OR [Environment] IS NULL) AND ([Application] = @Application OR [Application] IS NULL)";     public string Environment { get; set; }     public string ApplicationName { get; set; }     public bool ReloadOnChange { get; set; } = true;     public int ReloadInterval { get; set; } = 30;     public ILoggerFactory LoggerFactory { get; set; }      public IConfigurationProvider Build(IConfigurationBuilder builder)     {         return new DynamicDatabaseConfigurationProvider(this);     } }  public static class DynamicDatabaseConfigurationExtensions {     public static IConfigurationBuilder AddDynamicDatabaseConfiguration(         this IConfigurationBuilder builder,         string connectionString,         string environment,         string applicationName = null,         bool reloadOnChange = true,         int reloadInterval = 30,         ILoggerFactory loggerFactory = null)     {         return builder.Add(new DynamicDatabaseConfigurationSource         {             ConnectionString = connectionString,             Environment = environment,             ApplicationName = applicationName,             ReloadOnChange = reloadOnChange,             ReloadInterval = reloadInterval,             LoggerFactory = loggerFactory         });     } } Configuration Management API csharp // API for managing configuration in database [ApiController] [Route("api/[controller]")] public class ConfigurationController : ControllerBase {     private readonly ApplicationDbContext _context;     private readonly IConfiguration _configuration;     private readonly ILogger<ConfigurationController> _logger;      public ConfigurationController(         ApplicationDbContext context,         IConfiguration configuration,         ILogger<ConfigurationController> logger)     {         _context = context;         _configuration = configuration;         _logger = logger;     }      [HttpGet]     public async Task<ActionResult<IEnumerable<ConfigurationItem>>> GetConfiguration(         [FromQuery] string environment = null,         [FromQuery] string application = null)     {         var query = _context.Configuration.AsQueryable();          if (!string.IsNullOrEmpty(environment))         {             query = query.Where(c => c.Environment == environment || c.Environment == null);         }          if (!string.IsNullOrEmpty(application))         {             query = query.Where(c => c.Application == application || c.Application == null);         }          var items = await query.ToListAsync();         return Ok(items);     }      [HttpPost]     public async Task<ActionResult<ConfigurationItem>> CreateConfiguration(         ConfigurationItem item)     {         // Validate the configuration key         if (string.IsNullOrEmpty(item.Key))         {             return BadRequest("Key is required");         }          // Check if configuration already exists         var existing = await _context.Configuration             .Where(c => c.Key == item.Key &&                         c.Environment == item.Environment &&                         c.Application == item.Application)             .FirstOrDefaultAsync();          if (existing != null)         {             return Conflict($"Configuration with key '{item.Key}' already exists");         }          _context.Configuration.Add(item);         await _context.SaveChangesAsync();          _logger.LogInformation("Configuration created: {Key} for {Environment}/{Application}",              item.Key, item.Environment, item.Application);          return CreatedAtAction(nameof(GetConfigurationItem),              new { id = item.Id }, item);     }      [HttpPut("{id}")]     public async Task<IActionResult> UpdateConfiguration(int id, ConfigurationItem item)     {         if (id != item.Id)         {             return BadRequest();         }          var existing = await _context.Configuration.FindAsync(id);         if (existing == null)         {             return NotFound();         }          existing.Value = item.Value;         existing.UpdatedAt = DateTime.UtcNow;         existing.UpdatedBy = User.Identity.Name;          await _context.SaveChangesAsync();          _logger.LogInformation("Configuration updated: {Key}", existing.Key);          return NoContent();     }      [HttpDelete("{id}")]     public async Task<IActionResult> DeleteConfiguration(int id)     {         var item = await _context.Configuration.FindAsync(id);         if (item == null)         {             return NotFound();         }          _context.Configuration.Remove(item);         await _context.SaveChangesAsync();          _logger.LogInformation("Configuration deleted: {Key}", item.Key);          return NoContent();     }      [HttpGet("{id}")]     public async Task<ActionResult<ConfigurationItem>> GetConfigurationItem(int id)     {         var item = await _context.Configuration.FindAsync(id);         if (item == null)         {             return NotFound();         }         return item;     } }  // Configuration entity model public class ConfigurationItem {     public int Id { get; set; }          [Required]     [StringLength(200)]     public string Key { get; set; }          public string Value { get; set; }          [StringLength(50)]     public string Environment { get; set; }          [StringLength(50)]     public string Application { get; set; }          public string Description { get; set; }          public DateTime CreatedAt { get; set; } = DateTime.UtcNow;     public string CreatedBy { get; set; }          public DateTime? UpdatedAt { get; set; }     public string UpdatedBy { get; set; }          public bool IsSensitive { get; set; } } 12. Configuration Best Practices <a name="best-practices"></a> Security Best Practices csharp // Security-focused configuration validation public class SecurityConfigurationValidator {     private readonly IConfiguration _configuration;     private readonly ILogger<SecurityConfigurationValidator> _logger;      public SecurityConfigurationValidator(         IConfiguration configuration,         ILogger<SecurityConfigurationValidator> logger)     {         _configuration = configuration;         _logger = logger;     }      public void ValidateSecuritySettings()     {         ValidateNoSecretsInAppSettings();         ValidateConnectionStrings();         ValidateApiKeys();         ValidateJwtSettings();     }      private void ValidateNoSecretsInAppSettings()     {         var appSettingsPath = "appsettings.json";         if (File.Exists(appSettingsPath))         {             var content = File.ReadAllText(appSettingsPath);                          var sensitivePatterns = new[]             {                 @"(?i)password[=:""']([^""']+)",                 @"(?i)pwd[=:""']([^""']+)",                 @"(?i)secret[=:""']([^""']+)",                 @"(?i)key[=:""']([^""']+)",                 @"(?i)token[=:""']([^""']+)",                 @"sk_live_[a-zA-Z0-9]+",                 @"SG\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+"             };              foreach (var pattern in sensitivePatterns)             {                 var matches = System.Text.RegularExpressions.Regex.Matches(content, pattern);                 if (matches.Count > 0)                 {                     _logger.LogWarning(                         "Potential secrets found in appsettings.json. Pattern: {Pattern}. " +                         "Consider moving these to secure storage.", pattern);                 }             }         }     }      private void ValidateConnectionStrings()     {         var connectionStrings = _configuration.GetSection("ConnectionStrings").GetChildren();                  foreach (var connectionString in connectionStrings)         {             if (string.IsNullOrEmpty(connectionString.Value))             {                 throw new InvalidOperationException(                     $"Connection string '{connectionString.Key}' is empty");             }              // Check for weak passwords in connection strings             if (ContainsWeakPassword(connectionString.Value))             {                 _logger.LogWarning(                     "Connection string '{Key}' may contain weak password",                      connectionString.Key);             }         }     }      private void ValidateApiKeys()     {         var apiKeysSection = _configuration.GetSection("ApiKeys");         if (apiKeysSection.Exists())         {             foreach (var apiKey in apiKeysSection.GetChildren())             {                 if (string.IsNullOrEmpty(apiKey.Value))                 {                     throw new InvalidOperationException($"API key '{apiKey.Key}' is empty");                 }                  if (apiKey.Value.Length < 16)                 {                     _logger.LogWarning("API key '{Key}' may be too short", apiKey.Key);                 }             }         }     }      private void ValidateJwtSettings()     {         var jwtSection = _configuration.GetSection("Security:Jwt");         if (jwtSection.Exists())         {             var secretKey = jwtSection["SecretKey"];             if (string.IsNullOrEmpty(secretKey))             {                 throw new InvalidOperationException("JWT secret key is required");             }              if (secretKey.Length < 32)             {                 throw new InvalidOperationException(                     "JWT secret key must be at least 32 characters long");             }              if (secretKey.Equals("your-super-secret-key-here", StringComparison.OrdinalIgnoreCase))             {                 throw new InvalidOperationException(                     "JWT secret key must be changed from the default value");             }         }     }      private bool ContainsWeakPassword(string connectionString)     {         var weakPasswords = new[] { "password", "123456", "admin", "sa", "test" };         return weakPasswords.Any(weak =>              connectionString.Contains($"Password={weak}") ||              connectionString.Contains($"Pwd={weak}"));     } } Performance Optimization csharp // Configuration performance optimization public class OptimizedConfigurationService {     private readonly IConfiguration _configuration;     private readonly ConcurrentDictionary<string, object> _cache;     private readonly TimeSpan _cacheDuration;      public OptimizedConfigurationService(IConfiguration configuration)     {         _configuration = configuration;         _cache = new ConcurrentDictionary<string, object>();         _cacheDuration = TimeSpan.FromMinutes(5);     }      public T GetValue<T>(string key, T defaultValue = default)     {         var cacheKey = $"{typeof(T).Name}:{key}";                  if (_cache.TryGetValue(cacheKey, out var cachedValue) &&              cachedValue is CacheItem<T> cacheItem &&              cacheItem.Expiry > DateTime.UtcNow)         {             return cacheItem.Value;         }          var value = _configuration.GetValue(key, defaultValue);         _cache[cacheKey] = new CacheItem<T>(value, DateTime.UtcNow.Add(_cacheDuration));                  return value;     }      public T GetSection<T>(string sectionKey) where T : class, new()     {         var cacheKey = $"{typeof(T).Name}:{sectionKey}";                  if (_cache.TryGetValue(cacheKey, out var cachedValue) &&              cachedValue is CacheItem<T> cacheItem &&              cacheItem.Expiry > DateTime.UtcNow)         {             return cacheItem.Value;         }          var section = _configuration.GetSection(sectionKey);         var value = new T();         section.Bind(value);                  _cache[cacheKey] = new CacheItem<T>(value, DateTime.UtcNow.Add(_cacheDuration));                  return value;     }      public void ClearCache()     {         _cache.Clear();     }      public void RemoveFromCache(string key)     {         _cache.TryRemove(key, out _);     }      private class CacheItem<T>     {         public T Value { get; }         public DateTime Expiry { get; }          public CacheItem(T value, DateTime expiry)         {             Value = value;             Expiry = expiry;         }     } }  // Configuration change detection and cache invalidation public class ConfigurationChangeNotifier : IDisposable {     private readonly IConfiguration _configuration;     private readonly OptimizedConfigurationService _configService;     private readonly ILogger<ConfigurationChangeNotifier> _logger;     private readonly List<IDisposable> _changeCallbacks;      public ConfigurationChangeNotifier(         IConfiguration configuration,         OptimizedConfigurationService configService,         ILogger<ConfigurationChangeNotifier> logger)     {         _configuration = configuration;         _configService = configService;         _logger = logger;         _changeCallbacks = new List<IDisposable>();          SetupChangeDetection();     }      private void SetupChangeDetection()     {         // Monitor specific sections for changes         var sectionsToMonitor = new[] { "Database", "Features", "CacheSettings" };                  foreach (var section in sectionsToMonitor)         {             var changeToken = _configuration.GetReloadToken();             var callback = changeToken.RegisterChangeCallback(_ => OnConfigurationChanged(section), section);             _changeCallbacks.Add(callback);         }     }      private void OnConfigurationChanged(string section)     {         _logger.LogInformation("Configuration section '{Section}' changed, clearing cache", section);         _configService.ClearCache();                  // Re-register for changes         SetupChangeDetection();     }      public void Dispose()     {         foreach (var callback in _changeCallbacks)         {             callback?.Dispose();         }         _changeCallbacks.Clear();     } } 13. Security Considerations <a name="security"></a> Comprehensive Security Validation csharp // Advanced security configuration analyzer public class SecurityConfigurationAnalyzer {     private readonly IConfiguration _configuration;     private readonly IWebHostEnvironment _environment;     private readonly ILogger<SecurityConfigurationAnalyzer> _logger;      public SecurityConfigurationAnalyzer(         IConfiguration configuration,         IWebHostEnvironment environment,         ILogger<SecurityConfigurationAnalyzer> logger)     {         _configuration = configuration;         _environment = environment;         _logger = logger;     }      public SecurityAnalysisResult Analyze()     {         var result = new SecurityAnalysisResult();                  result.Issues.AddRange(CheckForHardcodedSecrets());         result.Issues.AddRange(CheckWeakEncryption());         result.Issues.AddRange(CheckInsecureProtocols());         result.Issues.AddRange(CheckExposedEndpoints());         result.Issues.AddRange(CheckCorsSettings());         result.Issues.AddRange(CheckJwtSecurity());                  result.Score = CalculateSecurityScore(result.Issues);                  return result;     }      private IEnumerable<SecurityIssue> CheckForHardcodedSecrets()     {         var issues = new List<SecurityIssue>();                  // Check appsettings for common secret patterns         var appSettingsPath = Path.Combine(_environment.ContentRootPath, "appsettings.json");         if (File.Exists(appSettingsPath))         {             var content = File.ReadAllText(appSettingsPath);                          var secretPatterns = new[]             {                 new { Pattern = @"(?i)[""']?password[""']?\s*[:=]\s*[""']([^""']+)[""']", Type = "Hardcoded Password" },                 new { Pattern = @"(?i)[""']?apikey[""']?\s*[:=]\s*[""']([^""']+)[""']", Type = "Hardcoded API Key" },                 new { Pattern = @"(?i)[""']?secret[""']?\s*[:=]\s*[""']([^""']+)[""']", Type = "Hardcoded Secret" },                 new { Pattern = @"sk_live_[a-zA-Z0-9]{24}", Type = "Stripe Secret Key" },                 new { Pattern = @"SG\.[a-zA-Z0-9_-]{22}\.[a-zA-Z0-9_-]{43}", Type = "SendGrid API Key" }             };              foreach (var pattern in secretPatterns)             {                 var matches = System.Text.RegularExpressions.Regex.Matches(content, pattern.Pattern);                 foreach (Match match in matches)                 {                     issues.Add(new SecurityIssue                     {                         Type = pattern.Type,                         Severity = SecuritySeverity.High,                         Message = $"{pattern.Type} found in appsettings.json",                         Recommendation = "Move to secure storage like Azure Key Vault or AWS Secrets Manager"                     });                 }             }         }                  return issues;     }      private IEnumerable<SecurityIssue> CheckWeakEncryption()     {         var issues = new List<SecurityIssue>();                  var jwtSecret = _configuration["Security:Jwt:SecretKey"];         if (!string.IsNullOrEmpty(jwtSecret) && jwtSecret.Length < 32)         {             issues.Add(new SecurityIssue             {                 Type = "Weak JWT Secret",                 Severity = SecuritySeverity.High,                 Message = "JWT secret key is too short (minimum 32 characters recommended)",                 Recommendation = "Generate a strong random secret key with at least 32 characters"             });         }                  return issues;     }      private IEnumerable<SecurityIssue> CheckInsecureProtocols()     {         var issues = new List<SecurityIssue>();                  var paymentUrl = _configuration["PaymentGateway:BaseUrl"];         if (!string.IsNullOrEmpty(paymentUrl) && paymentUrl.StartsWith("http://"))         {             issues.Add(new SecurityIssue             {                 Type = "Insecure Protocol",                 Severity = SecuritySeverity.Medium,                 Message = "Payment gateway URL uses HTTP instead of HTTPS",                 Recommendation = "Use HTTPS for all external service communications"             });         }                  return issues;     }      private IEnumerable<SecurityIssue> CheckExposedEndpoints()     {         var issues = new List<SecurityIssue>();                  if (_environment.IsProduction())         {             var enableSwagger = _configuration.GetValue<bool>("Features:EnableSwagger");             if (enableSwagger)             {                 issues.Add(new SecurityIssue                 {                     Type = "Exposed Development Tool",                     Severity = SecuritySeverity.Medium,                     Message = "Swagger is enabled in production environment",                     Recommendation = "Disable Swagger in production for security"                 });             }         }                  return issues;     }      private IEnumerable<SecurityIssue> CheckCorsSettings()     {         var issues = new List<SecurityIssue>();                  var corsOrigins = _configuration.GetSection("Security:Cors:AllowedOrigins").Get<string[]>();         if (corsOrigins != null && corsOrigins.Contains("*"))         {             issues.Add(new SecurityIssue             {                 Type = "Overly Permissive CORS",                 Severity = SecuritySeverity.High,                 Message = "CORS policy allows all origins (*)",                 Recommendation = "Restrict CORS to specific trusted domains"             });         }                  return issues;     }      private IEnumerable<SecurityIssue> CheckJwtSecurity()     {         var issues = new List<SecurityIssue>();                  var expiration = _configuration.GetValue<int>("Security:Jwt:ExpirationMinutes");         if (expiration > 1440) // 24 hours         {             issues.Add(new SecurityIssue             {                 Type = "Long JWT Expiration",                 Severity = SecuritySeverity.Medium,                 Message = $"JWT token expiration ({expiration} minutes) is too long",                 Recommendation = "Set JWT expiration to 15-60 minutes for better security"             });         }                  return issues;     }      private int CalculateSecurityScore(List<SecurityIssue> issues)     {         var baseScore = 100;                  foreach (var issue in issues)         {             baseScore -= issue.Severity switch             {                 SecuritySeverity.High => 20,                 SecuritySeverity.Medium => 10,                 SecuritySeverity.Low => 5,                 _ => 0             };         }                  return Math.Max(0, baseScore);     } }  public class SecurityAnalysisResult {     public List<SecurityIssue> Issues { get; set; } = new List<SecurityIssue>();     public int Score { get; set; }     public DateTime AnalyzedAt { get; set; } = DateTime.UtcNow; }  public class SecurityIssue {     public string Type { get; set; }     public SecuritySeverity Severity { get; set; }     public string Message { get; set; }     public string Recommendation { get; set; } }  public enum SecuritySeverity {     Low,     Medium,     High } 14. Troubleshooting Common Issues <a name="troubleshooting"></a> Configuration Troubleshooting Tools csharp // Comprehensive configuration diagnostics public class ConfigurationDiagnostics {     private readonly IConfiguration _configuration;     private readonly ILogger<ConfigurationDiagnostics> _logger;      public ConfigurationDiagnostics(IConfiguration configuration, ILogger<ConfigurationDiagnostics> logger)     {         _configuration = configuration;         _logger = logger;     }      public async Task<ConfigurationDiagnosticResult> RunDiagnosticsAsync()     {         var result = new ConfigurationDiagnosticResult();                  result.Issues.AddRange(await CheckConfigurationSourcesAsync());         result.Issues.AddRange(CheckRequiredSettings());         result.Issues.AddRange(CheckConfigurationValues());         result.Issues.AddRange(CheckExternalDependenciesAsync().GetAwaiter().GetResult());                  return result;     }      private async Task<List<DiagnosticIssue>> CheckConfigurationSourcesAsync()     {         var issues = new List<DiagnosticIssue>();                  // Check if appsettings files exist         var expectedFiles = new[] { "appsettings.json", $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json" };                  foreach (var file in expectedFiles)         {             if (!File.Exists(file))             {                 issues.Add(new DiagnosticIssue                 {                     Level = DiagnosticLevel.Warning,                     Category = "Configuration Files",                     Message = $"Configuration file '{file}' not found",                     Details = "This file is optional but recommended for environment-specific settings"                 });             }         }                  // Check environment variables         var requiredEnvVars = new[] { "ASPNETCORE_ENVIRONMENT" };         foreach (var envVar in requiredEnvVars)         {             if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envVar)))             {                 issues.Add(new DiagnosticIssue                 {                     Level = DiagnosticLevel.Warning,                     Category = "Environment Variables",                     Message = $"Environment variable '{envVar}' is not set",                     Details = "Defaulting to 'Production' environment"                 });             }         }                  return issues;     }      private List<DiagnosticIssue> CheckRequiredSettings()     {         var issues = new List<DiagnosticIssue>();                  var requiredSettings = new[]         {             "ConnectionStrings:DefaultConnection",             "Security:Jwt:SecretKey",             "Security:Jwt:Issuer",             "Security:Jwt:Audience"         };                  foreach (var setting in requiredSettings)         {             var value = _configuration[setting];             if (string.IsNullOrEmpty(value))             {                 issues.Add(new DiagnosticIssue                 {                     Level = DiagnosticLevel.Error,                     Category = "Required Settings",                     Message = $"Required configuration setting '{setting}' is missing or empty",                     Details = "This will cause application startup to fail"                 });             }         }                  return issues;     }      private List<DiagnosticIssue> CheckConfigurationValues()     {         var issues = new List<DiagnosticIssue>();                  // Check numeric values         var dbTimeout = _configuration.GetValue<int>("Database:Timeout", 0);         if (dbTimeout <= 0)         {             issues.Add(new DiagnosticIssue             {                 Level = DiagnosticLevel.Warning,                 Category = "Configuration Values",                 Message = "Database timeout is not set or invalid",                 Details = "Using default timeout of 30 seconds"             });         }                  // Check URL formats         var paymentUrl = _configuration["PaymentGateway:BaseUrl"];         if (!string.IsNullOrEmpty(paymentUrl) && !Uri.IsWellFormedUriString(paymentUrl, UriKind.Absolute))         {             issues.Add(new DiagnosticIssue             {                 Level = DiagnosticLevel.Error,                 Category = "Configuration Values",                 Message = "Payment gateway URL is not a valid URI",                 Details = "This will cause payment operations to fail"             });         }                  return issues;     }      private async Task<List<DiagnosticIssue>> CheckExternalDependenciesAsync()     {         var issues = new List<DiagnosticIssue>();                  // Check database connectivity         var connectionString = _configuration.GetConnectionString("DefaultConnection");         if (!string.IsNullOrEmpty(connectionString))         {             try             {                 await using var connection = new SqlConnection(connectionString);                 await connection.OpenAsync();                 await connection.CloseAsync();             }             catch (Exception ex)             {                 issues.Add(new DiagnosticIssue                 {                     Level = DiagnosticLevel.Error,                     Category = "External Dependencies",                     Message = "Cannot connect to database",                     Details = $"Database connection failed: {ex.Message}"                 });             }         }                  return issues;     } }  public class ConfigurationDiagnosticResult {     public List<DiagnosticIssue> Issues { get; set; } = new List<DiagnosticIssue>();     public DateTime DiagnosedAt { get; set; } = DateTime.UtcNow;     public bool HasErrors => Issues.Any(i => i.Level == DiagnosticLevel.Error); }  public class DiagnosticIssue {     public DiagnosticLevel Level { get; set; }     public string Category { get; set; }     public string Message { get; set; }     public string Details { get; set; } }  public enum DiagnosticLevel {     Information,     Warning,     Error }  // Configuration debugging middleware public class ConfigurationDebugMiddleware {     private readonly RequestDelegate _next;     private readonly IConfiguration _configuration;     private readonly ILogger<ConfigurationDebugMiddleware> _logger;      public ConfigurationDebugMiddleware(         RequestDelegate next,         IConfiguration configuration,         ILogger<ConfigurationDebugMiddleware> logger)     {         _next = next;         _configuration = configuration;         _logger = logger;     }      public async Task InvokeAsync(HttpContext context)     {         // Only enable in development         if (context.Request.Query.ContainsKey("debug-config"))         {             await WriteConfigurationDebugInfo(context);             return;         }          await _next(context);     }      private async Task WriteConfigurationDebugInfo(HttpContext context)     {         context.Response.ContentType = "application/json";                  var debugInfo = new         {             Environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"),             ConfigurationSources = GetConfigurationSources(),             AllSettings = GetAllConfigurationValues(),             EnvironmentVariables = GetRelevantEnvironmentVariables()         };                  var json = System.Text.Json.JsonSerializer.Serialize(debugInfo, new System.Text.Json.JsonSerializerOptions         {             WriteIndented = true         });                  await context.Response.WriteAsync(json);     }      private List<string> GetConfigurationSources()     {         // This would need reflection to access internal configuration providers         return new List<string>         {             "appsettings.json",             $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",             "Environment Variables",             "Command Line Arguments",             "User Secrets (Development only)"         };     }      private Dictionary<string, string> GetAllConfigurationValues()     {         var values = new Dictionary<string, string>();                  // Get all configuration values (be careful with secrets!)         foreach (var (key, value) in _configuration.AsEnumerable())         {             if (!string.IsNullOrEmpty(key) && !IsSensitiveKey(key))             {                 values[key] = value;             }         }                  return values;     }      private Dictionary<string, string> GetRelevantEnvironmentVariables()     {         var envVars = new Dictionary<string, string>();                  var relevantVars = Environment.GetEnvironmentVariables()             .Cast<System.Collections.DictionaryEntry>()             .Where(e => e.Key.ToString().StartsWith("ASPNETCORE_") ||                         e.Key.ToString().StartsWith("TECHMART_"))             .ToDictionary(e => e.Key.ToString(), e => e.Value.ToString());                  return relevantVars;     }      private bool IsSensitiveKey(string key)     {         var sensitiveKeywords = new[] { "password", "pwd", "secret", "key", "token", "connectionstring" };         return sensitiveKeywords.Any(keyword =>              key.Contains(keyword, StringComparison.OrdinalIgnoreCase));     } } 15. Real-World Implementation Examples <a name="real-world"></a> Enterprise-Grade Configuration Setup csharp // Complete enterprise configuration setup public class EnterpriseConfigurationBuilder {     public IHostBuilder CreateEnterpriseHostBuilder(string[] args, string applicationName)     {         return Host.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((context, config) =>             {                 var env = context.HostingEnvironment;                                  ConfigureEnterpriseAppSettings(config, env);                 ConfigureEnterpriseSecrets(config, env, applicationName);                 ConfigureEnterpriseExternalSources(config, env, applicationName);                 ConfigureEnterpriseMonitoring(config);             })             .ConfigureLogging((context, logging) =>             {                 logging.AddConfiguration(context.Configuration.GetSection("Logging"));                 logging.AddConsole();                 logging.AddDebug();                 logging.AddApplicationInsights();             })             .UseDefaultServiceProvider((context, options) =>             {                 options.ValidateScopes = context.HostingEnvironment.IsDevelopment();                 options.ValidateOnBuild = true;             });     }      private void ConfigureEnterpriseAppSettings(IConfigurationBuilder config, IHostEnvironment env)     {         // Base configuration         config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);                  // Environment-specific configuration         config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);                  // Environment-specific machine configuration (for overrides)         config.AddJsonFile($"appsettings.{env.EnvironmentName}.{Environment.MachineName}.json",              optional: true, reloadOnChange: true);     }      private void ConfigureEnterpriseSecrets(IConfigurationBuilder config, IHostEnvironment env, string applicationName)     {         if (env.IsDevelopment())         {             // User secrets for development             config.AddUserSecrets<Program>();         }         else         {             // Cloud secrets for non-development environments             var builtConfig = config.Build();                          // Azure Key Vault             var azureKeyVaultEndpoint = builtConfig["AzureKeyVault:Endpoint"];             if (!string.IsNullOrEmpty(azureKeyVaultEndpoint))             {                 config.AddAzureKeyVault(                     new Uri(azureKeyVaultEndpoint),                     new DefaultAzureCredential());             }                          // AWS Secrets Manager             var awsRegion = builtConfig["AWS:Region"];             var awsSecretName = builtConfig["AWS:Secrets:ApplicationSecretName"];             if (!string.IsNullOrEmpty(awsRegion) && !string.IsNullOrEmpty(awsSecretName))             {                 config.AddAwsSecretsManager(awsRegion, awsSecretName);             }         }     }      private void ConfigureEnterpriseExternalSources(IConfigurationBuilder config, IHostEnvironment env, string applicationName)     {         var builtConfig = config.Build();                  // Database configuration         var dbConnectionString = builtConfig.GetConnectionString("ConfigurationDb");         if (!string.IsNullOrEmpty(dbConnectionString))         {             config.AddDynamicDatabaseConfiguration(                 dbConnectionString,                 env.EnvironmentName,                 applicationName,                 reloadOnChange: true,                 reloadInterval: 60);         }                  // Consul configuration for microservices         var consulAddress = builtConfig["Consul:Address"];         if (!string.IsNullOrEmpty(consulAddress))         {             config.AddConsulKeyValue(consulAddress, $"{applicationName}/{env.EnvironmentName}");         }     }      private void ConfigureEnterpriseMonitoring(IConfigurationBuilder config)     {         // Application Insights         config.AddApplicationInsightsSettings();                  // Health check configuration         config.AddJsonFile("healthchecks.json", optional: true);     } }  // Real-world startup configuration public class EnterpriseStartup {     public EnterpriseStartup(IConfiguration configuration, IWebHostEnvironment env)     {         Configuration = configuration;         Environment = env;                  // Validate configuration on startup         ValidateConfiguration();     }      public IConfiguration Configuration { get; }     public IWebHostEnvironment Environment { get; }      private void ValidateConfiguration()     {         var validator = new EnterpriseConfigurationValidator(Configuration, Environment);         var result = validator.Validate();                  if (!result.IsValid)         {             throw new InvalidOperationException(                 $"Configuration validation failed: {string.Join(", ", result.Errors)}");         }     }      public void ConfigureServices(IServiceCollection services)     {         // Configuration validation         services.AddSingleton(new EnterpriseConfigurationValidator(Configuration, Environment));                  // Strongly-typed configuration         services.Configure<EnterpriseAppSettings>(Configuration);         services.Configure<DatabaseSettings>(Configuration.GetSection("Database"));         services.Configure<SecuritySettings>(Configuration.GetSection("Security"));         services.Configure<ExternalServicesSettings>(Configuration.GetSection("ExternalServices"));                  // Configuration-based service registration         ConfigureDatabaseServices(services);         ConfigureSecurityServices(services);         ConfigureExternalServices(services);         ConfigureApplicationServices(services);                  // Health checks         services.AddHealthChecks()             .AddSqlServer(Configuration.GetConnectionString("DefaultConnection"))             .AddUrlGroup(new Uri(Configuration["ExternalServices:PaymentGateway:HealthCheck"]))             .AddApplicationInsightsPublisher();                  // Caching         ConfigureCaching(services);     }      private void ConfigureDatabaseServices(IServiceCollection services)     {         var databaseSettings = Configuration.GetSection("Database").Get<DatabaseSettings>();                  services.AddDbContext<ApplicationDbContext>(options =>         {             options.UseSqlServer(databaseSettings.ConnectionString, sqlOptions =>             {                 sqlOptions.EnableRetryOnFailure(                     maxRetryCount: databaseSettings.RetryCount,                     maxRetryDelay: TimeSpan.FromSeconds(30),                     errorNumbersToAdd: null);             });                          if (Environment.IsDevelopment())             {                 options.EnableSensitiveDataLogging();                 options.EnableDetailedErrors();             }         });     }      private void ConfigureSecurityServices(IServiceCollection services)     {         var securitySettings = Configuration.GetSection("Security").Get<SecuritySettings>();                  services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)             .AddJwtBearer(options =>             {                 options.TokenValidationParameters = new TokenValidationParameters                 {                     ValidateIssuer = true,                     ValidateAudience = true,                     ValidateLifetime = true,                     ValidateIssuerSigningKey = true,                     ValidIssuer = securitySettings.Jwt.Issuer,                     ValidAudience = securitySettings.Jwt.Audience,                     IssuerSigningKey = new SymmetricSecurityKey(                         Encoding.UTF8.GetBytes(securitySettings.Jwt.SecretKey))                 };             });                  services.AddAuthorization(options =>         {             options.AddPolicy("AdminOnly", policy =>                  policy.RequireRole("Administrator"));         });     }      private void ConfigureExternalServices(IServiceCollection services)     {         var externalServices = Configuration.GetSection("ExternalServices").Get<ExternalServicesSettings>();                  // Configure HTTP clients with retry policies         services.AddHttpClient<IPaymentService, PaymentService>(client =>         {             client.BaseAddress = new Uri(externalServices.PaymentGateway.BaseUrl);             client.DefaultRequestHeaders.Add("X-API-Key", externalServices.PaymentGateway.ApiKey);         })         .AddPolicyHandler(GetRetryPolicy())         .AddPolicyHandler(GetCircuitBreakerPolicy());                  services.AddHttpClient<IEmailService, EmailService>(client =>         {             client.BaseAddress = new Uri(externalServices.EmailService.BaseUrl);         })         .AddPolicyHandler(GetRetryPolicy());     }      private void ConfigureApplicationServices(IServiceCollection services)     {         services.AddControllers();         services.AddSwaggerGen(c =>         {             c.SwaggerDoc("v1", new OpenApiInfo { Title = "Enterprise API", Version = "v1" });         });                  // Feature flags         var featureSettings = Configuration.GetSection("Features").Get<FeatureSettings>();         if (featureSettings.EnableCaching)         {             services.AddMemoryCache();         }                  if (featureSettings.EnableBackgroundServices)         {             services.AddHostedService<DataSyncService>();             services.AddHostedService<CleanupService>();         }     }      private void ConfigureCaching(IServiceCollection services)     {         var cacheSettings = Configuration.GetSection("Cache").Get<CacheSettings>();                  if (cacheSettings.Type == "Redis")         {             services.AddStackExchangeRedisCache(options =>             {                 options.Configuration = cacheSettings.RedisConnection;                 options.InstanceName = cacheSettings.InstanceName;             });         }         else         {             services.AddDistributedMemoryCache();         }     }      private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()     {         return HttpPolicyExtensions             .HandleTransientHttpError()             .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.TooManyRequests)             .WaitAndRetryAsync(                 retryCount: 3,                 sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),                 onRetry: (outcome, timespan, retryCount, context) =>                 {                     // Log retry attempts                 });     }      private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()     {         return HttpPolicyExtensions             .HandleTransientHttpError()             .CircuitBreakerAsync(                 handledEventsAllowedBeforeBreaking: 3,                 durationOfBreak: TimeSpan.FromSeconds(30));     }      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)     {         if (env.IsDevelopment())         {             app.UseDeveloperExceptionPage();             app.UseSwagger();             app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Enterprise API v1"));         }         else         {             app.UseExceptionHandler("/Error");             app.UseHsts();         }          app.UseHttpsRedirection();         app.UseRouting();                  app.UseAuthentication();         app.UseAuthorization();                  app.UseEndpoints(endpoints =>         {             endpoints.MapControllers();             endpoints.MapHealthChecks("/health");         });                  // Configuration diagnostics endpoint (development only)         if (env.IsDevelopment())         {             app.UseMiddleware<ConfigurationDebugMiddleware>();         }     } }  // Enterprise configuration classes public class EnterpriseAppSettings {     public string ApplicationName { get; set; }     public string Version { get; set; }     public string Environment { get; set; }     public FeatureSettings Features { get; set; }     public CacheSettings Cache { get; set; } }  public class FeatureSettings {     public bool EnableCaching { get; set; }     public bool EnableBackgroundServices { get; set; }     public bool EnableApiVersioning { get; set; }     public bool EnableResponseCompression { get; set; } }  public class CacheSettings {     public string Type { get; set; }     public string RedisConnection { get; set; }     public string InstanceName { get; set; }     public int DefaultExpiration { get; set; } = 3600; }  public class ExternalServicesSettings {     public PaymentGatewaySettings PaymentGateway { get; set; }     public EmailServiceSettings EmailService { get; set; }     public AnalyticsServiceSettings AnalyticsService { get; set; } }  public class PaymentGatewaySettings {     public string BaseUrl { get; set; }     public string ApiKey { get; set; }     public string WebhookSecret { get; set; }     public string HealthCheck { get; set; } }  public class EnterpriseConfigurationValidator {     private readonly IConfiguration _configuration;     private readonly IWebHostEnvironment _environment;      public EnterpriseConfigurationValidator(IConfiguration configuration, IWebHostEnvironment environment)     {         _configuration = configuration;         _environment = environment;     }      public ValidationResult Validate()     {         var errors = new List<string>();                  // Validate required settings         if (string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection")))         {             errors.Add("Default database connection string is required");         }                  // Validate security settings         var jwtSecret = _configuration["Security:Jwt:SecretKey"];         if (string.IsNullOrEmpty(jwtSecret) || jwtSecret.Length < 32)         {             errors.Add("JWT secret key must be at least 32 characters long");         }                  // Validate external services         var paymentUrl = _configuration["ExternalServices:PaymentGateway:BaseUrl"];         if (string.IsNullOrEmpty(paymentUrl))         {             errors.Add("Payment gateway base URL is required");         }                  return new ValidationResult         {             IsValid = !errors.Any(),             Errors = errors         };     } }  public class ValidationResult {     public bool IsValid { get; set; }     public List<string> Errors { get; set; } = new List<string>(); } This comprehensive guide covers ASP.NET Core configuration and secrets management from basic to advanced enterprise-level scenarios. The examples provided demonstrate real-world patterns and best practices that you can adapt for your specific application needs.  Remember to always prioritize security when handling configuration, especially when dealing with secrets and sensitive information. Use secure storage solutions like Azure Key Vault or AWS Secrets Manager in production environments, and never commit secrets to source control. ASP.NET Core Configuration and Secrets Mastery: Complete Guide Table of Contents  Introduction to Configuration in ASP.NET Core  Understanding the Configuration System  AppSettings.json Deep Dive  Environment-Specific Configuration  User Secrets for Development  Environment Variables Configuration  Command-Line Configuration  Custom Configuration Providers  Azure Key Vault Integration  AWS Secrets Manager  Database Configuration Provider  Configuration Best Practices  Security Considerations  Troubleshooting Common Issues  Real-World Implementation Examples  1. Introduction to Configuration in ASP.NET Core <a name="introduction"></a> Configuration management is a critical aspect of modern web application development. In ASP.NET Core, the configuration system has been completely redesigned to be more flexible, extensible, and cloud-ready. Let's explore why proper configuration management is essential:  Why Configuration Management Matters Real-Life Scenario: Imagine you're developing an e-commerce application that needs to connect to different databases in development, staging, and production environments. Without proper configuration management, you'd be constantly changing connection strings, risking security breaches and deployment failures.  csharp // Problematic approach - hardcoded configuration public class DatabaseService {     private string _connectionString = "Server=prod-db;Database=Shop;User=admin;Password=secret123";          public void Connect()     {         // This will fail in development and staging!     } } Evolution of Configuration in ASP.NET From Web.config to Modern Approach:  ASP.NET Web Forms: XML-based Web.config with complex sections  ASP.NET MVC: Still Web.config with some improvements  ASP.NET Core: JSON-based, environment-aware, cloud-native  2. Understanding the Configuration System <a name="understanding-system"></a> Configuration Building Blocks The ASP.NET Core configuration system is built around several key concepts:  IConfiguration Interface csharp public interface IConfiguration {     string this[string key] { get; set; }     IConfigurationSection GetSection(string key);     IEnumerable<IConfigurationSection> GetChildren();     IChangeToken GetReloadToken(); } Configuration Sources Hierarchy ASP.NET Core loads configuration from multiple sources in a specific order:  csharp public class Program {     public static void Main(string[] args)     {         CreateHostBuilder(args).Build().Run();     }      public static IHostBuilder CreateHostBuilder(string[] args) =>         Host.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((hostingContext, config) =>             {                 // Configuration sources are loaded in this order:                 // 1. appsettings.json                 // 2. appsettings.{Environment}.json                 // 3. User Secrets (Development environment only)                 // 4. Environment Variables                 // 5. Command-line arguments             })             .ConfigureWebHostDefaults(webBuilder =>             {                 webBuilder.UseStartup<Startup>();             }); } Configuration Providers Deep Dive csharp // Detailed configuration setup with multiple providers public static IHostBuilder CreateHostBuilder(string[] args) =>     Host.CreateDefaultBuilder(args)         .ConfigureAppConfiguration((context, config) =>         {             var env = context.HostingEnvironment;                          // Base appsettings             config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);                          // Environment-specific appsettings             config.AddJsonFile($"appsettings.{env.EnvironmentName}.json",                  optional: true, reloadOnChange: true);                          // User Secrets for development             if (env.IsDevelopment())             {                 config.AddUserSecrets<Program>();             }                          // Environment variables             config.AddEnvironmentVariables();                          // Command-line arguments             if (args != null)             {                 config.AddCommandLine(args);             }                          // Last provider wins - command line has highest priority         }); 3. AppSettings.json Deep Dive <a name="appsettings-json"></a> Structured Configuration with JSON Real-Life Example: E-commerce application configuration  json {   "StoreSettings": {     "StoreName": "TechMart Online",     "MaxProductsPerPage": 50,     "EnableWishlist": true,     "Currency": "USD",     "SupportedCountries": ["US", "CA", "UK", "AU"]   },   "Database": {     "ConnectionString": "Server=localhost;Database=TechMart;Trusted_Connection=true;",     "Timeout": 30,     "RetryCount": 3   },   "PaymentGateway": {     "ApiKey": "pk_test_123456789",     "BaseUrl": "https://api.payments.com/v1",     "WebhookSecret": "whsec_987654321",     "Settings": {       "Timeout": 10000,       "RetryPolicy": "ExponentialBackoff"     }   },   "EmailSettings": {     "SmtpServer": "smtp.techmart.com",     "Port": 587,     "Username": "noreply@techmart.com",     "FromAddress": "noreply@techmart.com",     "Templates": {       "OrderConfirmation": "templates/order-confirmation.html",       "PasswordReset": "templates/password-reset.html"     }   },   "CacheSettings": {     "RedisConnection": "localhost:6379",     "DefaultExpiration": 3600,     "Enabled": true   },   "Security": {     "Jwt": {       "SecretKey": "your-super-secret-key-here",       "Issuer": "TechMart",       "Audience": "TechMartUsers",       "ExpirationMinutes": 60     },     "Cors": {       "AllowedOrigins": ["https://techmart.com", "https://admin.techmart.com"]     }   } } Strongly-Typed Configuration Classes csharp // Configuration classes for strongly-typed access public class StoreSettings {     public string StoreName { get; set; }     public int MaxProductsPerPage { get; set; }     public bool EnableWishlist { get; set; }     public string Currency { get; set; }     public string[] SupportedCountries { get; set; } }  public class DatabaseSettings {     public string ConnectionString { get; set; }     public int Timeout { get; set; }     public int RetryCount { get; set; } }  public class PaymentGatewaySettings {     public string ApiKey { get; set; }     public string BaseUrl { get; set; }     public string WebhookSecret { get; set; }     public PaymentSettings Settings { get; set; } }  public class PaymentSettings {     public int Timeout { get; set; }     public string RetryPolicy { get; set; } }  public class EmailSettings {     public string SmtpServer { get; set; }     public int Port { get; set; }     public string Username { get; set; }     public string FromAddress { get; set; }     public EmailTemplates Templates { get; set; } }  public class EmailTemplates {     public string OrderConfirmation { get; set; }     public string PasswordReset { get; set; } }  public class CacheSettings {     public string RedisConnection { get; set; }     public int DefaultExpiration { get; set; }     public bool Enabled { get; set; } }  public class SecuritySettings {     public JwtSettings Jwt { get; set; }     public CorsSettings Cors { get; set; } }  public class JwtSettings {     public string SecretKey { get; set; }     public string Issuer { get; set; }     public string Audience { get; set; }     public int ExpirationMinutes { get; set; } }  public class CorsSettings {     public string[] AllowedOrigins { get; set; } } Configuration Binding and Validation csharp // Startup configuration with validation public class Startup {     private readonly IConfiguration _configuration;      public Startup(IConfiguration configuration)     {         _configuration = configuration;     }      public void ConfigureServices(IServiceCollection services)     {         // Bind configuration sections to strongly-typed classes         services.Configure<StoreSettings>(_configuration.GetSection("StoreSettings"));         services.Configure<DatabaseSettings>(_configuration.GetSection("Database"));         services.Configure<PaymentGatewaySettings>(_configuration.GetSection("PaymentGateway"));         services.Configure<EmailSettings>(_configuration.GetSection("EmailSettings"));         services.Configure<CacheSettings>(_configuration.GetSection("CacheSettings"));         services.Configure<SecuritySettings>(_configuration.GetSection("Security"));          // Advanced binding with validation         var storeSettings = new StoreSettings();         _configuration.GetSection("StoreSettings").Bind(storeSettings);                  // Validate critical settings         if (string.IsNullOrEmpty(storeSettings.StoreName))         {             throw new InvalidOperationException("StoreName is required in configuration");         }          // Register services that use configuration         services.AddSingleton(storeSettings);                  // Database configuration with validation         var dbSettings = _configuration.GetSection("Database").Get<DatabaseSettings>();         if (string.IsNullOrEmpty(dbSettings?.ConnectionString))         {             throw new InvalidOperationException("Database connection string is required");         }                  services.AddDbContext<ApplicationDbContext>(options =>             options.UseSqlServer(dbSettings.ConnectionString));     } } 4. Environment-Specific Configuration <a name="environment-config"></a> Environment-Based Configuration Strategy Real-Life Scenario: Different configurations for Development, Staging, and Production environments  json // appsettings.Development.json {   "Logging": {     "LogLevel": {       "Default": "Debug",       "Microsoft": "Debug",       "Microsoft.Hosting.Lifetime": "Debug"     }   },   "Database": {     "ConnectionString": "Server=localhost;Database=TechMart_Dev;Trusted_Connection=true;",     "Timeout": 30,     "RetryCount": 3   },   "PaymentGateway": {     "BaseUrl": "https://api.sandbox.payments.com/v1",     "ApiKey": "pk_test_development_key"   },   "Features": {     "EnableSwagger": true,     "EnableDetailedErrors": true,     "UseInMemoryCache": true   } }  // appsettings.Staging.json {   "Logging": {     "LogLevel": {       "Default": "Information",       "Microsoft": "Warning",       "Microsoft.Hosting.Lifetime": "Information"     }   },   "Database": {     "ConnectionString": "Server=staging-db.techmart.com;Database=TechMart_Staging;User Id=appuser;Password=staging_password;",     "Timeout": 30,     "RetryCount": 5   },   "PaymentGateway": {     "BaseUrl": "https://api.staging.payments.com/v1",     "ApiKey": "pk_test_staging_key"   },   "Features": {     "EnableSwagger": false,     "EnableDetailedErrors": true,     "UseInMemoryCache": false   } }  // appsettings.Production.json {   "Logging": {     "LogLevel": {       "Default": "Warning",       "Microsoft": "Warning",       "Microsoft.Hosting.Lifetime": "Warning"     }   },   "Database": {     "ConnectionString": "Server=prod-db.techmart.com;Database=TechMart_Prod;User Id=appuser;Password=production_password;",     "Timeout": 30,     "RetryCount": 5   },   "PaymentGateway": {     "BaseUrl": "https://api.payments.com/v1",     "ApiKey": "pk_live_production_key"   },   "Features": {     "EnableSwagger": false,     "EnableDetailedErrors": false,     "UseInMemoryCache": false   } } Environment Detection and Configuration csharp // Program.cs with environment-specific setup public class Program {     public static void Main(string[] args)     {         CreateHostBuilder(args).Build().Run();     }      public static IHostBuilder CreateHostBuilder(string[] args) =>         Host.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((context, config) =>             {                 var env = context.HostingEnvironment;                                  Console.WriteLine($"Environment: {env.EnvironmentName}");                 Console.WriteLine($"Content Root: {env.ContentRootPath}");                 Console.WriteLine($"Web Root: {env.WebRootPath}");                                  // Load environment-specific configuration                 config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)                       .AddJsonFile($"appsettings.{env.EnvironmentName}.json",                                     optional: true, reloadOnChange: true);                                  // Additional configuration based on environment                 if (env.IsDevelopment())                 {                     // Development-specific configuration                     config.AddUserSecrets<Program>();                 }                 else if (env.IsStaging())                 {                     // Staging-specific configuration                     config.AddJsonFile("appsettings.Staging.Secrets.json",                                        optional: true, reloadOnChange: true);                 }                 else if (env.IsProduction())                 {                     // Production-specific configuration                     // Rely on environment variables and secure vaults                 }             })             .ConfigureWebHostDefaults(webBuilder =>             {                 webBuilder.UseStartup<Startup>();             }); } Environment-Based Service Registration csharp // Environment-specific service configuration public class Startup {     public Startup(IConfiguration configuration, IWebHostEnvironment env)     {         Configuration = configuration;         Environment = env;     }      public IConfiguration Configuration { get; }     public IWebHostEnvironment Environment { get; }      public void ConfigureServices(IServiceCollection services)     {         // Common services for all environments         services.AddControllers();         services.AddHttpClient();                  // Environment-specific services         if (Environment.IsDevelopment())         {             services.AddDatabaseDeveloperPageExceptionFilter();             services.AddSwaggerGen(c =>             {                 c.SwaggerDoc("v1", new OpenApiInfo { Title = "TechMart API", Version = "v1" });             });         }          // Database configuration based on environment         if (Environment.IsDevelopment())         {             services.AddDbContext<ApplicationDbContext>(options =>                 options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))                        .EnableSensitiveDataLogging());         }         else         {             services.AddDbContext<ApplicationDbContext>(options =>                 options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));         }          // Cache configuration         if (Configuration.GetValue<bool>("Features:UseInMemoryCache"))         {             services.AddMemoryCache();         }         else         {             var redisConnection = Configuration.GetValue<string>("CacheSettings:RedisConnection");             services.AddStackExchangeRedisCache(options =>             {                 options.Configuration = redisConnection;             });         }     }      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)     {         if (env.IsDevelopment())         {             app.UseDeveloperExceptionPage();             app.UseSwagger();             app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TechMart API v1"));         }         else         {             app.UseExceptionHandler("/Error");             app.UseHsts();         }          app.UseHttpsRedirection();         app.UseRouting();         app.UseAuthorization();         app.UseEndpoints(endpoints =>         {             endpoints.MapControllers();         });     } } 5. User Secrets for Development <a name="user-secrets"></a> Why Use User Secrets? Real-Life Problem: Developers committing sensitive data to source control  csharp // Before User Secrets - sensitive data in appsettings.json {   "ConnectionStrings": {     "DefaultConnection": "Server=localhost;Database=MyApp;User Id=sa;Password=MySuperSecretPassword123!"   },   "ApiKeys": {     "SendGrid": "SG.abc123def456ghi789",     "Stripe": "sk_test_1234567890abcdef"   } } Setting Up User Secrets Step 1: Initialize User Secrets bash # In the project directory dotnet user-secrets init Step 2: Add Secrets bash # Add connection string dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=localhost;Database=MyApp;User Id=sa;Password=DevPassword123!"  # Add API keys dotnet user-secrets set "ApiKeys:SendGrid" "SG.devkey123456789" dotnet user-secrets set "ApiKeys:Stripe" "sk_test_devkey123456789"  # Add JWT secret dotnet user-secrets set "Security:Jwt:SecretKey" "dev-super-secret-jwt-key-2024" Step 3: secrets.json File Structure json {   "ConnectionStrings:DefaultConnection": "Server=localhost;Database=MyApp_Dev;User Id=sa;Password=DevPassword123!",   "ApiKeys": {     "SendGrid": "SG.devkey123456789",     "Stripe": "sk_test_devkey123456789"   },   "Security:Jwt:SecretKey": "dev-super-secret-jwt-key-2024",   "PaymentGateway": {     "ApiKey": "pk_test_dev_123456789",     "WebhookSecret": "whsec_dev_987654321"   } } Programmatic Access to User Secrets csharp // Advanced User Secrets management public class DevelopmentSecretsManager {     private readonly IConfiguration _configuration;      public DevelopmentSecretsManager(IConfiguration configuration)     {         _configuration = configuration;     }      public void ValidateDevelopmentSecrets()     {         var requiredSecrets = new[]         {             "ConnectionStrings:DefaultConnection",             "ApiKeys:SendGrid",             "Security:Jwt:SecretKey"         };          var missingSecrets = requiredSecrets             .Where(secret => string.IsNullOrEmpty(_configuration[secret]))             .ToList();          if (missingSecrets.Any())         {             throw new InvalidOperationException(                 $"Missing required development secrets: {string.Join(", ", missingSecrets)}. " +                 "Run 'dotnet user-secrets set [key] [value]' to set them.");         }     }      public string GetSecret(string key)     {         var value = _configuration[key];         if (string.IsNullOrEmpty(value))         {             throw new ArgumentException($"Secret '{key}' not found in user secrets");         }         return value;     }      public T GetSecret<T>(string key)     {         var value = GetSecret(key);         return (T)Convert.ChangeType(value, typeof(T));     } }  // Integration in Startup public class Startup {     public Startup(IConfiguration configuration, IWebHostEnvironment env)     {         Configuration = configuration;         Environment = env;     }      public IConfiguration Configuration { get; }     public IWebHostEnvironment Environment { get; }      public void ConfigureServices(IServiceCollection services)     {         // Validate secrets in development         if (Environment.IsDevelopment())         {             var secretsManager = new DevelopmentSecretsManager(Configuration);             secretsManager.ValidateDevelopmentSecrets();         }          // Use secrets in services         var connectionString = Configuration.GetConnectionString("DefaultConnection");         services.AddDbContext<ApplicationDbContext>(options =>             options.UseSqlServer(connectionString));     } } User Secrets Best Practices csharp // Secure development practices public static class SecretsBestPractices {     public static void EnsureSecretsAreNotInAppSettings(IWebHostEnvironment env)     {         if (env.IsDevelopment())         {             var appSettingsPath = Path.Combine(env.ContentRootPath, "appsettings.json");             var appSettingsContent = File.ReadAllText(appSettingsPath);                          var sensitivePatterns = new[]             {                 @"password=([^;""']+)",                 @"pwd=([^;""']+)",                 @"api[_-]?key=([^;""']+)",                 @"secret=([^;""']+)"             };              foreach (var pattern in sensitivePatterns)             {                 var matches = System.Text.RegularExpressions.Regex.Matches(appSettingsContent, pattern,                      System.Text.RegularExpressions.RegexOptions.IgnoreCase);                                  if (matches.Count > 0)                 {                     throw new InvalidOperationException(                         "Sensitive data found in appsettings.json. Move to user secrets.");                 }             }         }     } } 6. Environment Variables Configuration <a name="environment-variables"></a> Environment Variables in Different Environments Real-Life Scenario: Deployment to various environments (Docker, Azure, AWS, Kubernetes)  csharp // Environment variable configuration provider public static class EnvironmentVariablesConfig {     public static void ConfigureEnvironmentVariables(this IConfigurationBuilder config)     {         config.AddEnvironmentVariables();                  // Add prefix for application-specific variables         config.AddEnvironmentVariables("TECHMART_");     } }  // Usage in Program.cs public static IHostBuilder CreateHostBuilder(string[] args) =>     Host.CreateDefaultBuilder(args)         .ConfigureAppConfiguration((context, config) =>         {             config.AddJsonFile("appsettings.json", optional: false)                   .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json",                                optional: true)                   .AddEnvironmentVariables("TECHMART_") // Application-specific                   .AddEnvironmentVariables(); // All environment variables         }); Environment Variable Naming Conventions csharp // Environment variable mapping examples public static class EnvVarConstants {     // Database     public const string DB_CONNECTION = "TECHMART_DB_CONNECTION";     public const string DB_TIMEOUT = "TECHMART_DB_TIMEOUT";          // API Keys     public const string SENDGRID_API_KEY = "TECHMART_SENDGRID_API_KEY";     public const string STRIPE_API_KEY = "TECHMART_STRIPE_API_KEY";          // Application Settings     public const string ENVIRONMENT = "ASPNETCORE_ENVIRONMENT";     public const string URLs = "ASPNETCORE_URLS";          // Feature Flags     public const string FEATURE_SWAGGER = "TECHMART_FEATURE_SWAGGER";     public const string FEATURE_CACHE = "TECHMART_FEATURE_CACHE"; }  // Environment variable helper class public class EnvironmentConfig {     private readonly IConfiguration _configuration;      public EnvironmentConfig(IConfiguration configuration)     {         _configuration = configuration;     }      public string DatabaseConnection =>          GetRequiredValue(EnvVarConstants.DB_CONNECTION);      public string SendGridApiKey =>          GetRequiredValue(EnvVarConstants.SENDGRID_API_KEY);      public bool EnableSwagger =>          GetValue(EnvVarConstants.FEATURE_SWAGGER, false);      public int DatabaseTimeout =>          GetValue(EnvVarConstants.DB_TIMEOUT, 30);      private string GetRequiredValue(string key)     {         var value = _configuration[key];         if (string.IsNullOrEmpty(value))         {             throw new InvalidOperationException($"Required environment variable '{key}' is missing");         }         return value;     }      private T GetValue<T>(string key, T defaultValue)     {         var value = _configuration[key];         if (string.IsNullOrEmpty(value))         {             return defaultValue;         }          try         {             return (T)Convert.ChangeType(value, typeof(T));         }         catch (Exception ex)         {             throw new InvalidOperationException(                 $"Unable to convert environment variable '{key}' value '{value}' to type {typeof(T).Name}", ex);         }     } } Docker and Container Configuration dockerfile # Dockerfile with environment variables FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443  FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["TechMart.Web/TechMart.Web.csproj", "TechMart.Web/"] RUN dotnet restore "TechMart.Web/TechMart.Web.csproj" COPY . . WORKDIR "/src/TechMart.Web" RUN dotnet build "TechMart.Web.csproj" -c Release -o /app/build  FROM build AS publish RUN dotnet publish "TechMart.Web.csproj" -c Release -o /app/publish  FROM base AS final WORKDIR /app COPY --from=publish /app/publish .  # Environment variables for container ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:80 ENV TECHMART_DB_TIMEOUT=30 ENV TECHMART_FEATURE_SWAGGER=false  ENTRYPOINT ["dotnet", "TechMart.Web.dll"] yaml # docker-compose.yml with environment variables version: '3.8'  services:   techmart.web:     image: techmart/web:latest     build:       context: .       dockerfile: TechMart.Web/Dockerfile     environment:       - ASPNETCORE_ENVIRONMENT=Development       - TECHMART_DB_CONNECTION=Server=techmart.db;Database=TechMart_Dev;User Id=sa;Password=DevPassword123!       - TECHMART_SENDGRID_API_KEY=SG.docker_dev_key       - TECHMART_STRIPE_API_KEY=sk_test_docker_key       - TECHMART_FEATURE_SWAGGER=true     ports:       - "5000:80"     depends_on:       - techmart.db    techmart.db:     image: mcr.microsoft.com/mssql/server:2019-latest     environment:       - SA_PASSWORD=DevPassword123!       - ACCEPT_EULA=Y     ports:       - "1433:1433" 7. Command-Line Configuration <a name="command-line"></a> Command-Line Arguments in ASP.NET Core Real-Life Scenario: Overriding configuration for specific deployments or debugging  csharp // Command-line configuration setup public class Program {     public static void Main(string[] args)     {         CreateHostBuilder(args).Build().Run();     }      public static IHostBuilder CreateHostBuilder(string[] args) =>         Host.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((context, config) =>             {                 // Configure command-line arguments with custom mappings                 var switchMappings = new Dictionary<string, string>                 {                     { "--urls", "urls" },                     { "--environment", "environment" },                     { "--db-connection", "ConnectionStrings:DefaultConnection" },                     { "--enable-swagger", "Features:EnableSwagger" },                     { "--cache-timeout", "CacheSettings:DefaultExpiration" },                     { "--log-level", "Logging:LogLevel:Default" }                 };                  config.AddCommandLine(args, switchMappings);             })             .ConfigureWebHostDefaults(webBuilder =>             {                 webBuilder.UseStartup<Startup>();             }); } Advanced Command-Line Processing csharp // Custom command-line argument processor public class CommandLineConfig {     private readonly string[] _args;      public CommandLineConfig(string[] args)     {         _args = args;     }      public Dictionary<string, string> ParseArguments()     {         var config = new Dictionary<string, string>();                  for (int i = 0; i < _args.Length; i++)         {             var arg = _args[i];                          if (arg.StartsWith("--"))             {                 var key = arg.Substring(2);                 string value = "true"; // Default for flags                  // Check if next argument is a value (not another flag)                 if (i + 1 < _args.Length && !_args[i + 1].StartsWith("--"))                 {                     value = _args[i + 1];                     i++; // Skip the value in next iteration                 }                  config[key] = value;             }             else if (arg.StartsWith("/"))             {                 // Windows-style arguments: /key value or /key:value                 var parts = arg.Substring(1).Split(':');                 var key = parts[0];                 var value = parts.Length > 1 ? parts[1] : "true";                  config[key] = value;             }             else if (arg.Contains("="))             {                 // Key=value format                 var parts = arg.Split('=');                 if (parts.Length == 2)                 {                     config[parts[0]] = parts[1];                 }             }         }          return config;     }      public void ValidateRequiredArguments(Dictionary<string, string> arguments)     {         var requiredArgs = new[] { "db-connection", "environment" };         var missingArgs = requiredArgs.Where(arg => !arguments.ContainsKey(arg)).ToList();          if (missingArgs.Any())         {             throw new ArgumentException(                 $"Missing required command-line arguments: {string.Join(", ", missingArgs)}");         }     } }  // Integration with configuration public static class CommandLineConfigExtensions {     public static IConfigurationBuilder AddCustomCommandLine(         this IConfigurationBuilder builder,          string[] args)     {         var commandLineConfig = new CommandLineConfig(args);         var arguments = commandLineConfig.ParseArguments();                  // Validate required arguments         commandLineConfig.ValidateRequiredArguments(arguments);                  // Add to configuration         foreach (var (key, value) in arguments)         {             Environment.SetEnvironmentVariable($"CMDLINE_{key}", value);         }          return builder.AddInMemoryCollection(arguments);     } } Real-World Command-Line Usage Examples bash # Development with specific settings dotnet run --urls "https://localhost:5001" --environment "Development" --db-connection "Server=localhost;Database=DevDB;Trusted_Connection=true" --enable-swagger true --log-level "Debug"  # Production with minimal logging dotnet run --urls "http://*:80" --environment "Production" --db-connection "Server=prod-db;Database=ProdDB;User Id=appuser;Password=ProdPass123!" --enable-swagger false --log-level "Warning"  # Docker container with environment overrides docker run -p 8080:80 techmart/app --db-connection "Server=sql-server;Database=AppDB;User Id=sa;Password=DockerPass123!" --cache-timeout 3600 8. Custom Configuration Providers <a name="custom-providers"></a> Building Custom Configuration Providers Real-Life Scenario: Reading configuration from a custom XML file or external service  csharp // Custom XML configuration provider public class XmlConfigurationProvider : ConfigurationProvider {     private readonly string _filePath;      public XmlConfigurationProvider(string filePath)     {         _filePath = filePath;     }      public override void Load()     {         var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);                  try         {             if (File.Exists(_filePath))             {                 var doc = XDocument.Load(_filePath);                 ParseXmlElement(doc.Root, "", data);             }         }         catch (Exception ex)         {             throw new InvalidOperationException($"Failed to load XML configuration from {_filePath}", ex);         }          Data = data;     }      private void ParseXmlElement(XElement element, string prefix, Dictionary<string, string> data)     {         foreach (var child in element.Elements())         {             var currentKey = string.IsNullOrEmpty(prefix)                  ? child.Name.LocalName                  : $"{prefix}:{child.Name.LocalName}";              if (child.HasElements)             {                 ParseXmlElement(child, currentKey, data);             }             else             {                 data[currentKey] = child.Value;             }         }     } }  public class XmlConfigurationSource : IConfigurationSource {     public string FilePath { get; set; }      public IConfigurationProvider Build(IConfigurationBuilder builder)     {         return new XmlConfigurationProvider(FilePath);     } }  public static class XmlConfigurationExtensions {     public static IConfigurationBuilder AddXmlFile(         this IConfigurationBuilder builder,          string path,          bool optional = false)     {         if (builder == null)         {             throw new ArgumentNullException(nameof(builder));         }          if (string.IsNullOrEmpty(path))         {             throw new ArgumentException("File path must not be null or empty", nameof(path));         }          var source = new XmlConfigurationSource         {             FilePath = path,             Optional = optional         };          builder.Add(source);         return builder;     } } Database Configuration Provider csharp // Database configuration provider for dynamic configuration public class DatabaseConfigurationProvider : ConfigurationProvider, IDisposable {     private readonly DatabaseConfigurationSource _source;     private readonly Timer _refreshTimer;     private bool _disposed = false;      public DatabaseConfigurationProvider(DatabaseConfigurationSource source)     {         _source = source;                  if (_source.ReloadOnChange && _source.ReloadInterval > 0)         {             _refreshTimer = new Timer(RefreshConfiguration, null,                  TimeSpan.FromSeconds(_source.ReloadInterval),                  TimeSpan.FromSeconds(_source.ReloadInterval));         }     }      public override void Load()     {         RefreshConfiguration();     }      private void RefreshConfiguration(object state = null)     {         try         {             var newData = LoadConfigurationFromDatabase();                          // Only update if configuration changed             if (!Data.SequenceEqual(newData))             {                 Data = newData;                 OnReload(); // Notify about configuration changes             }         }         catch (Exception ex)         {             // Log error but don't crash the application             Console.WriteLine($"Failed to refresh configuration from database: {ex.Message}");         }     }      private Dictionary<string, string> LoadConfigurationFromDatabase()     {         var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);                  using var connection = new SqlConnection(_source.ConnectionString);         connection.Open();                  var command = new SqlCommand(             "SELECT [Key], [Value], [Environment] FROM Configuration WHERE [Environment] = @Environment OR [Environment] IS NULL",              connection);                  command.Parameters.AddWithValue("@Environment", _source.Environment);                  using var reader = command.ExecuteReader();         while (reader.Read())         {             var key = reader.GetString(0);             var value = reader.GetString(1);             data[key] = value;         }                  return data;     }      public void Dispose()     {         if (!_disposed)         {             _refreshTimer?.Dispose();             _disposed = true;         }     } }  public class DatabaseConfigurationSource : IConfigurationSource {     public string ConnectionString { get; set; }     public string Environment { get; set; }     public bool ReloadOnChange { get; set; }     public int ReloadInterval { get; set; } = 30; // seconds      public IConfigurationProvider Build(IConfigurationBuilder builder)     {         return new DatabaseConfigurationProvider(this);     } }  public static class DatabaseConfigurationExtensions {     public static IConfigurationBuilder AddDatabaseConfiguration(         this IConfigurationBuilder builder,         string connectionString,         string environment,         bool reloadOnChange = false,         int reloadInterval = 30)     {         return builder.Add(new DatabaseConfigurationSource         {             ConnectionString = connectionString,             Environment = environment,             ReloadOnChange = reloadOnChange,             ReloadInterval = reloadInterval         });     } } 9. Azure Key Vault Integration <a name="azure-key-vault"></a> Securing Secrets with Azure Key Vault Real-Life Scenario: Enterprise application with multiple environments and compliance requirements  csharp // Azure Key Vault configuration provider public class Program {     public static async Task Main(string[] args)     {         var host = CreateHostBuilder(args).Build();                  // Validate Key Vault connectivity         await ValidateKeyVaultConnection(host.Services);                  await host.RunAsync();     }      public static IHostBuilder CreateHostBuilder(string[] args) =>         Host.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((context, config) =>             {                 var builtConfig = config.Build();                                  // Add Azure Key Vault                 var keyVaultEndpoint = builtConfig["AzureKeyVault:Endpoint"];                 if (!string.IsNullOrEmpty(keyVaultEndpoint))                 {                     var azureServiceTokenProvider = new AzureServiceTokenProvider();                     var keyVaultClient = new KeyVaultClient(                         new KeyVaultClient.AuthenticationCallback(                             azureServiceTokenProvider.KeyVaultTokenCallback));                                          config.AddAzureKeyVault(                         keyVaultEndpoint,                         keyVaultClient,                         new DefaultKeyVaultSecretManager());                 }             })             .ConfigureWebHostDefaults(webBuilder =>             {                 webBuilder.UseStartup<Startup>();             });      private static async Task ValidateKeyVaultConnection(IServiceProvider services)     {         try         {             var configuration = services.GetRequiredService<IConfiguration>();             var keyVaultEndpoint = configuration["AzureKeyVault:Endpoint"];                          if (!string.IsNullOrEmpty(keyVaultEndpoint))             {                 var secretClient = new SecretClient(new Uri(keyVaultEndpoint),                      new DefaultAzureCredential());                                  // Test connection by trying to list secrets                 await secretClient.GetPropertiesOfSecretsAsync().FirstAsync();                                  Console.WriteLine("✅ Azure Key Vault connection successful");             }         }         catch (Exception ex)         {             Console.WriteLine($"❌ Azure Key Vault connection failed: {ex.Message}");             throw;         }     } } Advanced Key Vault Management csharp // Key Vault secret management service public class KeyVaultSecretManager {     private readonly SecretClient _secretClient;     private readonly ILogger<KeyVaultSecretManager> _logger;      public KeyVaultSecretManager(IConfiguration configuration, ILogger<KeyVaultSecretManager> logger)     {         var keyVaultEndpoint = configuration["AzureKeyVault:Endpoint"];         if (string.IsNullOrEmpty(keyVaultEndpoint))         {             throw new InvalidOperationException("Azure Key Vault endpoint is not configured");         }          _secretClient = new SecretClient(new Uri(keyVaultEndpoint), new DefaultAzureCredential());         _logger = logger;     }      public async Task<string> GetSecretAsync(string secretName)     {         try         {             var secret = await _secretClient.GetSecretAsync(secretName);             return secret.Value.Value;         }         catch (RequestFailedException ex) when (ex.Status == 404)         {             _logger.LogWarning("Secret '{SecretName}' not found in Key Vault", secretName);             return null;         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to retrieve secret '{SecretName}' from Key Vault", secretName);             throw;         }     }      public async Task SetSecretAsync(string secretName, string secretValue)     {         try         {             await _secretClient.SetSecretAsync(secretName, secretValue);             _logger.LogInformation("Secret '{SecretName}' updated in Key Vault", secretName);         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to set secret '{SecretName}' in Key Vault", secretName);             throw;         }     }      public async Task<IEnumerable<string>> ListSecretsAsync()     {         var secrets = new List<string>();                  await foreach (var secretProperties in _secretClient.GetPropertiesOfSecretsAsync())         {             secrets.Add(secretProperties.Name);         }                  return secrets;     }      public async Task<bool> SecretExistsAsync(string secretName)     {         try         {             await _secretClient.GetSecretAsync(secretName);             return true;         }         catch (RequestFailedException ex) when (ex.Status == 404)         {             return false;         }     } }  // Startup configuration for Key Vault public class Startup {     public Startup(IConfiguration configuration, IWebHostEnvironment env)     {         Configuration = configuration;         Environment = env;     }      public IConfiguration Configuration { get; }     public IWebHostEnvironment Environment { get; }      public void ConfigureServices(IServiceCollection services)     {         // Register Key Vault service         services.AddSingleton<KeyVaultSecretManager>();                  // Configure database using Key Vault         services.AddDbContext<ApplicationDbContext>(options =>         {             var connectionString = Configuration.GetConnectionString("DefaultConnection");             options.UseSqlServer(connectionString);         });          // Configure other services with secrets from Key Vault         services.Configure<PaymentGatewaySettings>(options =>         {             options.ApiKey = Configuration["PaymentGateway--ApiKey"];             options.WebhookSecret = Configuration["PaymentGateway--WebhookSecret"];         });     } } Key Vault Secret Rotation csharp // Secret rotation service public class SecretRotationService : BackgroundService {     private readonly KeyVaultSecretManager _secretManager;     private readonly IConfiguration _configuration;     private readonly ILogger<SecretRotationService> _logger;      public SecretRotationService(         KeyVaultSecretManager secretManager,         IConfiguration configuration,         ILogger<SecretRotationService> logger)     {         _secretManager = secretManager;         _configuration = configuration;         _logger = logger;     }      protected override async Task ExecuteAsync(CancellationToken stoppingToken)     {         while (!stoppingToken.IsCancellationRequested)         {             try             {                 await RotateSecretsIfNeeded();                 await Task.Delay(TimeSpan.FromHours(24), stoppingToken); // Check daily             }             catch (Exception ex)             {                 _logger.LogError(ex, "Secret rotation failed");                 await Task.Delay(TimeSpan.FromHours(1), stoppingToken); // Retry after 1 hour             }         }     }      private async Task RotateSecretsIfNeeded()     {         var secretsToRotate = new[] { "DatabasePassword", "ApiKey--Primary", "JwtSecret" };                  foreach (var secretName in secretsToRotate)         {             if (await ShouldRotateSecret(secretName))             {                 await RotateSecret(secretName);             }         }     }      private async Task<bool> ShouldRotateSecret(string secretName)     {         // Check secret age or other rotation criteria         var secret = await _secretManager.GetSecretAsync(secretName);         if (secret == null) return false;          // Implement rotation logic based on your requirements         return false; // Placeholder     }      private async Task RotateSecret(string secretName)     {         _logger.LogInformation("Rotating secret: {SecretName}", secretName);                  // Generate new secret value         var newSecretValue = GenerateNewSecret(secretName);                  // Set new version in Key Vault         await _secretManager.SetSecretAsync(secretName, newSecretValue);                  _logger.LogInformation("Successfully rotated secret: {SecretName}", secretName);     }      private string GenerateNewSecret(string secretName)     {         return secretName switch         {             "DatabasePassword" => GenerateSecurePassword(),             "ApiKey--Primary" => GenerateApiKey(),             "JwtSecret" => GenerateJwtSecret(),             _ => Guid.NewGuid().ToString()         };     }      private string GenerateSecurePassword()     {         const string validChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*";         var random = new Random();         return new string(Enumerable.Repeat(validChars, 32)             .Select(s => s[random.Next(s.Length)]).ToArray());     }      private string GenerateApiKey() => $"key_{Guid.NewGuid():N}";     private string GenerateJwtSecret() => Convert.ToBase64String(Guid.NewGuid().ToByteArray()); } 10. AWS Secrets Manager <a name="aws-secrets"></a> AWS Secrets Manager Integration Real-Life Scenario: Multi-cloud deployment with AWS infrastructure  csharp // AWS Secrets Manager configuration provider public class AwsSecretsManagerConfigurationProvider : ConfigurationProvider {     private readonly string _region;     private readonly string _secretName;     private readonly IAmazonSecretsManager _secretsClient;      public AwsSecretsManagerConfigurationProvider(string region, string secretName)     {         _region = region;         _secretName = secretName;         _secretsClient = new AmazonSecretsManagerClient(RegionEndpoint.GetBySystemName(region));     }      public override void Load()     {         try         {             var secret = GetSecretValueAsync().GetAwaiter().GetResult();             var data = ParseSecretString(secret);             Data = data;         }         catch (Exception ex)         {             throw new InvalidOperationException($"Failed to load secrets from AWS Secrets Manager: {ex.Message}", ex);         }     }      private async Task<string> GetSecretValueAsync()     {         var request = new GetSecretValueRequest         {             SecretId = _secretName         };          var response = await _secretsClient.GetSecretValueAsync(request);         return response.SecretString;     }      private Dictionary<string, string> ParseSecretString(string secretString)     {         var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);                  try         {             var json = JsonDocument.Parse(secretString);             ParseJsonElement(json.RootElement, "", data);         }         catch (JsonException)         {             // If not JSON, treat as simple key-value pairs             data[_secretName] = secretString;         }                  return data;     }      private void ParseJsonElement(JsonElement element, string prefix, Dictionary<string, string> data)     {         switch (element.ValueKind)         {             case JsonValueKind.Object:                 foreach (var property in element.EnumerateObject())                 {                     var currentKey = string.IsNullOrEmpty(prefix)                          ? property.Name                          : $"{prefix}:{property.Name}";                     ParseJsonElement(property.Value, currentKey, data);                 }                 break;                              case JsonValueKind.Array:                 var index = 0;                 foreach (var item in element.EnumerateArray())                 {                     var currentKey = $"{prefix}:{index}";                     ParseJsonElement(item, currentKey, data);                     index++;                 }                 break;                              default:                 data[prefix] = element.ToString();                 break;         }     } }  public class AwsSecretsManagerConfigurationSource : IConfigurationSource {     public string Region { get; set; }     public string SecretName { get; set; }      public IConfigurationProvider Build(IConfigurationBuilder builder)     {         return new AwsSecretsManagerConfigurationProvider(Region, SecretName);     } }  public static class AwsSecretsManagerConfigurationExtensions {     public static IConfigurationBuilder AddAwsSecretsManager(         this IConfigurationBuilder builder,         string region,         string secretName)     {         return builder.Add(new AwsSecretsManagerConfigurationSource         {             Region = region,             SecretName = secretName         });     } } Multi-Cloud Secret Management csharp // Unified secret management service public interface ISecretManager {     Task<string> GetSecretAsync(string secretName);     Task SetSecretAsync(string secretName, string secretValue);     Task<bool> SecretExistsAsync(string secretName); }  public class MultiCloudSecretManager : ISecretManager {     private readonly KeyVaultSecretManager _azureSecretManager;     private readonly AwsSecretManager _awsSecretManager;     private readonly IConfiguration _configuration;     private readonly ILogger<MultiCloudSecretManager> _logger;      public MultiCloudSecretManager(         KeyVaultSecretManager azureSecretManager,         AwsSecretManager awsSecretManager,         IConfiguration configuration,         ILogger<MultiCloudSecretManager> logger)     {         _azureSecretManager = azureSecretManager;         _awsSecretManager = awsSecretManager;         _configuration = configuration;         _logger = logger;     }      public async Task<string> GetSecretAsync(string secretName)     {         // Determine which cloud provider to use based on configuration         var cloudProvider = _configuration["CloudProvider"] ?? "Azure";                  try         {             return cloudProvider switch             {                 "Azure" => await _azureSecretManager.GetSecretAsync(secretName),                 "AWS" => await _awsSecretManager.GetSecretAsync(secretName),                 _ => throw new InvalidOperationException($"Unsupported cloud provider: {cloudProvider}")             };         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to retrieve secret '{SecretName}' from {CloudProvider}",                  secretName, cloudProvider);             throw;         }     }      public async Task SetSecretAsync(string secretName, string secretValue)     {         var cloudProvider = _configuration["CloudProvider"] ?? "Azure";                  try         {             switch (cloudProvider)             {                 case "Azure":                     await _azureSecretManager.SetSecretAsync(secretName, secretValue);                     break;                 case "AWS":                     await _awsSecretManager.SetSecretAsync(secretName, secretValue);                     break;                 default:                     throw new InvalidOperationException($"Unsupported cloud provider: {cloudProvider}");             }                          _logger.LogInformation("Secret '{SecretName}' updated in {CloudProvider}",                  secretName, cloudProvider);         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to set secret '{SecretName}' in {CloudProvider}",                  secretName, cloudProvider);             throw;         }     }      public async Task<bool> SecretExistsAsync(string secretName)     {         var cloudProvider = _configuration["CloudProvider"] ?? "Azure";                  return cloudProvider switch         {             "Azure" => await _azureSecretManager.SecretExistsAsync(secretName),             "AWS" => await _awsSecretManager.SecretExistsAsync(secretName),             _ => throw new InvalidOperationException($"Unsupported cloud provider: {cloudProvider}")         };     } }  // AWS Secret Manager implementation public class AwsSecretManager {     private readonly IAmazonSecretsManager _secretsClient;     private readonly ILogger<AwsSecretManager> _logger;      public AwsSecretManager(string region, ILogger<AwsSecretManager> logger)     {         _secretsClient = new AmazonSecretsManagerClient(RegionEndpoint.GetBySystemName(region));         _logger = logger;     }      public async Task<string> GetSecretAsync(string secretName)     {         try         {             var request = new GetSecretValueRequest { SecretId = secretName };             var response = await _secretsClient.GetSecretValueAsync(request);             return response.SecretString;         }         catch (ResourceNotFoundException)         {             _logger.LogWarning("Secret '{SecretName}' not found in AWS Secrets Manager", secretName);             return null;         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to retrieve secret '{SecretName}' from AWS Secrets Manager", secretName);             throw;         }     }      public async Task SetSecretAsync(string secretName, string secretValue)     {         try         {             var request = new PutSecretValueRequest             {                 SecretId = secretName,                 SecretString = secretValue             };                          await _secretsClient.PutSecretValueAsync(request);         }         catch (Exception ex)         {             _logger.LogError(ex, "Failed to set secret '{SecretName}' in AWS Secrets Manager", secretName);             throw;         }     }      public async Task<bool> SecretExistsAsync(string secretName)     {         try         {             await GetSecretAsync(secretName);             return true;         }         catch (ResourceNotFoundException)         {             return false;         }     } } 11. Database Configuration Provider <a name="database-provider"></a> Dynamic Database Configuration Real-Life Scenario: Application that needs runtime configuration changes without redeployment  csharp // Advanced database configuration provider public class DynamicDatabaseConfigurationProvider : ConfigurationProvider, IDisposable {     private readonly DynamicDatabaseConfigurationSource _source;     private readonly Timer _refreshTimer;     private readonly ILogger<DynamicDatabaseConfigurationProvider> _logger;     private bool _disposed = false;      public DynamicDatabaseConfigurationProvider(DynamicDatabaseConfigurationSource source)     {         _source = source;         _logger = source.LoggerFactory?.CreateLogger<DynamicDatabaseConfigurationProvider>();          if (_source.ReloadOnChange)         {             _refreshTimer = new Timer(async _ => await RefreshConfigurationAsync(),                  null,                  TimeSpan.FromSeconds(_source.ReloadInterval),                  TimeSpan.FromSeconds(_source.ReloadInterval));         }     }      public override void Load()     {         LoadAsync().GetAwaiter().GetResult();     }      private async Task LoadAsync()     {         try         {             await RefreshConfigurationAsync();         }         catch (Exception ex)         {             _logger?.LogError(ex, "Failed to load configuration from database");             throw;         }     }      private async Task RefreshConfigurationAsync()     {         try         {             var newData = await LoadConfigurationFromDatabaseAsync();                          if (!Data.SequenceEqual(newData))             {                 Data = newData;                 OnReload();                 _logger?.LogInformation("Configuration reloaded from database");             }         }         catch (Exception ex)         {             _logger?.LogError(ex, "Failed to refresh configuration from database");         }     }      private async Task<Dictionary<string, string>> LoadConfigurationFromDatabaseAsync()     {         var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);                  await using var connection = new SqlConnection(_source.ConnectionString);         await connection.OpenAsync();                  var command = new SqlCommand(_source.Query, connection);         command.Parameters.AddWithValue("@Environment", _source.Environment);         command.Parameters.AddWithValue("@Application", _source.ApplicationName);                  await using var reader = await command.ExecuteReaderAsync();         while (await reader.ReadAsync())         {             var key = reader.GetString(0);             var value = reader.IsDBNull(1) ? null : reader.GetString(1);             data[key] = value;         }                  return data;     }      public void Dispose()     {         if (!_disposed)         {             _refreshTimer?.Dispose();             _disposed = true;         }     } }  public class DynamicDatabaseConfigurationSource : IConfigurationSource {     public string ConnectionString { get; set; }     public string Query { get; set; } =          "SELECT [Key], [Value] FROM Configuration WHERE ([Environment] = @Environment OR [Environment] IS NULL) AND ([Application] = @Application OR [Application] IS NULL)";     public string Environment { get; set; }     public string ApplicationName { get; set; }     public bool ReloadOnChange { get; set; } = true;     public int ReloadInterval { get; set; } = 30;     public ILoggerFactory LoggerFactory { get; set; }      public IConfigurationProvider Build(IConfigurationBuilder builder)     {         return new DynamicDatabaseConfigurationProvider(this);     } }  public static class DynamicDatabaseConfigurationExtensions {     public static IConfigurationBuilder AddDynamicDatabaseConfiguration(         this IConfigurationBuilder builder,         string connectionString,         string environment,         string applicationName = null,         bool reloadOnChange = true,         int reloadInterval = 30,         ILoggerFactory loggerFactory = null)     {         return builder.Add(new DynamicDatabaseConfigurationSource         {             ConnectionString = connectionString,             Environment = environment,             ApplicationName = applicationName,             ReloadOnChange = reloadOnChange,             ReloadInterval = reloadInterval,             LoggerFactory = loggerFactory         });     } } Configuration Management API csharp // API for managing configuration in database [ApiController] [Route("api/[controller]")] public class ConfigurationController : ControllerBase {     private readonly ApplicationDbContext _context;     private readonly IConfiguration _configuration;     private readonly ILogger<ConfigurationController> _logger;      public ConfigurationController(         ApplicationDbContext context,         IConfiguration configuration,         ILogger<ConfigurationController> logger)     {         _context = context;         _configuration = configuration;         _logger = logger;     }      [HttpGet]     public async Task<ActionResult<IEnumerable<ConfigurationItem>>> GetConfiguration(         [FromQuery] string environment = null,         [FromQuery] string application = null)     {         var query = _context.Configuration.AsQueryable();          if (!string.IsNullOrEmpty(environment))         {             query = query.Where(c => c.Environment == environment || c.Environment == null);         }          if (!string.IsNullOrEmpty(application))         {             query = query.Where(c => c.Application == application || c.Application == null);         }          var items = await query.ToListAsync();         return Ok(items);     }      [HttpPost]     public async Task<ActionResult<ConfigurationItem>> CreateConfiguration(         ConfigurationItem item)     {         // Validate the configuration key         if (string.IsNullOrEmpty(item.Key))         {             return BadRequest("Key is required");         }          // Check if configuration already exists         var existing = await _context.Configuration             .Where(c => c.Key == item.Key &&                         c.Environment == item.Environment &&                         c.Application == item.Application)             .FirstOrDefaultAsync();          if (existing != null)         {             return Conflict($"Configuration with key '{item.Key}' already exists");         }          _context.Configuration.Add(item);         await _context.SaveChangesAsync();          _logger.LogInformation("Configuration created: {Key} for {Environment}/{Application}",              item.Key, item.Environment, item.Application);          return CreatedAtAction(nameof(GetConfigurationItem),              new { id = item.Id }, item);     }      [HttpPut("{id}")]     public async Task<IActionResult> UpdateConfiguration(int id, ConfigurationItem item)     {         if (id != item.Id)         {             return BadRequest();         }          var existing = await _context.Configuration.FindAsync(id);         if (existing == null)         {             return NotFound();         }          existing.Value = item.Value;         existing.UpdatedAt = DateTime.UtcNow;         existing.UpdatedBy = User.Identity.Name;          await _context.SaveChangesAsync();          _logger.LogInformation("Configuration updated: {Key}", existing.Key);          return NoContent();     }      [HttpDelete("{id}")]     public async Task<IActionResult> DeleteConfiguration(int id)     {         var item = await _context.Configuration.FindAsync(id);         if (item == null)         {             return NotFound();         }          _context.Configuration.Remove(item);         await _context.SaveChangesAsync();          _logger.LogInformation("Configuration deleted: {Key}", item.Key);          return NoContent();     }      [HttpGet("{id}")]     public async Task<ActionResult<ConfigurationItem>> GetConfigurationItem(int id)     {         var item = await _context.Configuration.FindAsync(id);         if (item == null)         {             return NotFound();         }         return item;     } }  // Configuration entity model public class ConfigurationItem {     public int Id { get; set; }          [Required]     [StringLength(200)]     public string Key { get; set; }          public string Value { get; set; }          [StringLength(50)]     public string Environment { get; set; }          [StringLength(50)]     public string Application { get; set; }          public string Description { get; set; }          public DateTime CreatedAt { get; set; } = DateTime.UtcNow;     public string CreatedBy { get; set; }          public DateTime? UpdatedAt { get; set; }     public string UpdatedBy { get; set; }          public bool IsSensitive { get; set; } } 12. Configuration Best Practices <a name="best-practices"></a> Security Best Practices csharp // Security-focused configuration validation public class SecurityConfigurationValidator {     private readonly IConfiguration _configuration;     private readonly ILogger<SecurityConfigurationValidator> _logger;      public SecurityConfigurationValidator(         IConfiguration configuration,         ILogger<SecurityConfigurationValidator> logger)     {         _configuration = configuration;         _logger = logger;     }      public void ValidateSecuritySettings()     {         ValidateNoSecretsInAppSettings();         ValidateConnectionStrings();         ValidateApiKeys();         ValidateJwtSettings();     }      private void ValidateNoSecretsInAppSettings()     {         var appSettingsPath = "appsettings.json";         if (File.Exists(appSettingsPath))         {             var content = File.ReadAllText(appSettingsPath);                          var sensitivePatterns = new[]             {                 @"(?i)password[=:""']([^""']+)",                 @"(?i)pwd[=:""']([^""']+)",                 @"(?i)secret[=:""']([^""']+)",                 @"(?i)key[=:""']([^""']+)",                 @"(?i)token[=:""']([^""']+)",                 @"sk_live_[a-zA-Z0-9]+",                 @"SG\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+"             };              foreach (var pattern in sensitivePatterns)             {                 var matches = System.Text.RegularExpressions.Regex.Matches(content, pattern);                 if (matches.Count > 0)                 {                     _logger.LogWarning(                         "Potential secrets found in appsettings.json. Pattern: {Pattern}. " +                         "Consider moving these to secure storage.", pattern);                 }             }         }     }      private void ValidateConnectionStrings()     {         var connectionStrings = _configuration.GetSection("ConnectionStrings").GetChildren();                  foreach (var connectionString in connectionStrings)         {             if (string.IsNullOrEmpty(connectionString.Value))             {                 throw new InvalidOperationException(                     $"Connection string '{connectionString.Key}' is empty");             }              // Check for weak passwords in connection strings             if (ContainsWeakPassword(connectionString.Value))             {                 _logger.LogWarning(                     "Connection string '{Key}' may contain weak password",                      connectionString.Key);             }         }     }      private void ValidateApiKeys()     {         var apiKeysSection = _configuration.GetSection("ApiKeys");         if (apiKeysSection.Exists())         {             foreach (var apiKey in apiKeysSection.GetChildren())             {                 if (string.IsNullOrEmpty(apiKey.Value))                 {                     throw new InvalidOperationException($"API key '{apiKey.Key}' is empty");                 }                  if (apiKey.Value.Length < 16)                 {                     _logger.LogWarning("API key '{Key}' may be too short", apiKey.Key);                 }             }         }     }      private void ValidateJwtSettings()     {         var jwtSection = _configuration.GetSection("Security:Jwt");         if (jwtSection.Exists())         {             var secretKey = jwtSection["SecretKey"];             if (string.IsNullOrEmpty(secretKey))             {                 throw new InvalidOperationException("JWT secret key is required");             }              if (secretKey.Length < 32)             {                 throw new InvalidOperationException(                     "JWT secret key must be at least 32 characters long");             }              if (secretKey.Equals("your-super-secret-key-here", StringComparison.OrdinalIgnoreCase))             {                 throw new InvalidOperationException(                     "JWT secret key must be changed from the default value");             }         }     }      private bool ContainsWeakPassword(string connectionString)     {         var weakPasswords = new[] { "password", "123456", "admin", "sa", "test" };         return weakPasswords.Any(weak =>              connectionString.Contains($"Password={weak}") ||              connectionString.Contains($"Pwd={weak}"));     } } Performance Optimization csharp // Configuration performance optimization public class OptimizedConfigurationService {     private readonly IConfiguration _configuration;     private readonly ConcurrentDictionary<string, object> _cache;     private readonly TimeSpan _cacheDuration;      public OptimizedConfigurationService(IConfiguration configuration)     {         _configuration = configuration;         _cache = new ConcurrentDictionary<string, object>();         _cacheDuration = TimeSpan.FromMinutes(5);     }      public T GetValue<T>(string key, T defaultValue = default)     {         var cacheKey = $"{typeof(T).Name}:{key}";                  if (_cache.TryGetValue(cacheKey, out var cachedValue) &&              cachedValue is CacheItem<T> cacheItem &&              cacheItem.Expiry > DateTime.UtcNow)         {             return cacheItem.Value;         }          var value = _configuration.GetValue(key, defaultValue);         _cache[cacheKey] = new CacheItem<T>(value, DateTime.UtcNow.Add(_cacheDuration));                  return value;     }      public T GetSection<T>(string sectionKey) where T : class, new()     {         var cacheKey = $"{typeof(T).Name}:{sectionKey}";                  if (_cache.TryGetValue(cacheKey, out var cachedValue) &&              cachedValue is CacheItem<T> cacheItem &&              cacheItem.Expiry > DateTime.UtcNow)         {             return cacheItem.Value;         }          var section = _configuration.GetSection(sectionKey);         var value = new T();         section.Bind(value);                  _cache[cacheKey] = new CacheItem<T>(value, DateTime.UtcNow.Add(_cacheDuration));                  return value;     }      public void ClearCache()     {         _cache.Clear();     }      public void RemoveFromCache(string key)     {         _cache.TryRemove(key, out _);     }      private class CacheItem<T>     {         public T Value { get; }         public DateTime Expiry { get; }          public CacheItem(T value, DateTime expiry)         {             Value = value;             Expiry = expiry;         }     } }  // Configuration change detection and cache invalidation public class ConfigurationChangeNotifier : IDisposable {     private readonly IConfiguration _configuration;     private readonly OptimizedConfigurationService _configService;     private readonly ILogger<ConfigurationChangeNotifier> _logger;     private readonly List<IDisposable> _changeCallbacks;      public ConfigurationChangeNotifier(         IConfiguration configuration,         OptimizedConfigurationService configService,         ILogger<ConfigurationChangeNotifier> logger)     {         _configuration = configuration;         _configService = configService;         _logger = logger;         _changeCallbacks = new List<IDisposable>();          SetupChangeDetection();     }      private void SetupChangeDetection()     {         // Monitor specific sections for changes         var sectionsToMonitor = new[] { "Database", "Features", "CacheSettings" };                  foreach (var section in sectionsToMonitor)         {             var changeToken = _configuration.GetReloadToken();             var callback = changeToken.RegisterChangeCallback(_ => OnConfigurationChanged(section), section);             _changeCallbacks.Add(callback);         }     }      private void OnConfigurationChanged(string section)     {         _logger.LogInformation("Configuration section '{Section}' changed, clearing cache", section);         _configService.ClearCache();                  // Re-register for changes         SetupChangeDetection();     }      public void Dispose()     {         foreach (var callback in _changeCallbacks)         {             callback?.Dispose();         }         _changeCallbacks.Clear();     } } 13. Security Considerations <a name="security"></a> Comprehensive Security Validation csharp // Advanced security configuration analyzer public class SecurityConfigurationAnalyzer {     private readonly IConfiguration _configuration;     private readonly IWebHostEnvironment _environment;     private readonly ILogger<SecurityConfigurationAnalyzer> _logger;      public SecurityConfigurationAnalyzer(         IConfiguration configuration,         IWebHostEnvironment environment,         ILogger<SecurityConfigurationAnalyzer> logger)     {         _configuration = configuration;         _environment = environment;         _logger = logger;     }      public SecurityAnalysisResult Analyze()     {         var result = new SecurityAnalysisResult();                  result.Issues.AddRange(CheckForHardcodedSecrets());         result.Issues.AddRange(CheckWeakEncryption());         result.Issues.AddRange(CheckInsecureProtocols());         result.Issues.AddRange(CheckExposedEndpoints());         result.Issues.AddRange(CheckCorsSettings());         result.Issues.AddRange(CheckJwtSecurity());                  result.Score = CalculateSecurityScore(result.Issues);                  return result;     }      private IEnumerable<SecurityIssue> CheckForHardcodedSecrets()     {         var issues = new List<SecurityIssue>();                  // Check appsettings for common secret patterns         var appSettingsPath = Path.Combine(_environment.ContentRootPath, "appsettings.json");         if (File.Exists(appSettingsPath))         {             var content = File.ReadAllText(appSettingsPath);                          var secretPatterns = new[]             {                 new { Pattern = @"(?i)[""']?password[""']?\s*[:=]\s*[""']([^""']+)[""']", Type = "Hardcoded Password" },                 new { Pattern = @"(?i)[""']?apikey[""']?\s*[:=]\s*[""']([^""']+)[""']", Type = "Hardcoded API Key" },                 new { Pattern = @"(?i)[""']?secret[""']?\s*[:=]\s*[""']([^""']+)[""']", Type = "Hardcoded Secret" },                 new { Pattern = @"sk_live_[a-zA-Z0-9]{24}", Type = "Stripe Secret Key" },                 new { Pattern = @"SG\.[a-zA-Z0-9_-]{22}\.[a-zA-Z0-9_-]{43}", Type = "SendGrid API Key" }             };              foreach (var pattern in secretPatterns)             {                 var matches = System.Text.RegularExpressions.Regex.Matches(content, pattern.Pattern);                 foreach (Match match in matches)                 {                     issues.Add(new SecurityIssue                     {                         Type = pattern.Type,                         Severity = SecuritySeverity.High,                         Message = $"{pattern.Type} found in appsettings.json",                         Recommendation = "Move to secure storage like Azure Key Vault or AWS Secrets Manager"                     });                 }             }         }                  return issues;     }      private IEnumerable<SecurityIssue> CheckWeakEncryption()     {         var issues = new List<SecurityIssue>();                  var jwtSecret = _configuration["Security:Jwt:SecretKey"];         if (!string.IsNullOrEmpty(jwtSecret) && jwtSecret.Length < 32)         {             issues.Add(new SecurityIssue             {                 Type = "Weak JWT Secret",                 Severity = SecuritySeverity.High,                 Message = "JWT secret key is too short (minimum 32 characters recommended)",                 Recommendation = "Generate a strong random secret key with at least 32 characters"             });         }                  return issues;     }      private IEnumerable<SecurityIssue> CheckInsecureProtocols()     {         var issues = new List<SecurityIssue>();                  var paymentUrl = _configuration["PaymentGateway:BaseUrl"];         if (!string.IsNullOrEmpty(paymentUrl) && paymentUrl.StartsWith("http://"))         {             issues.Add(new SecurityIssue             {                 Type = "Insecure Protocol",                 Severity = SecuritySeverity.Medium,                 Message = "Payment gateway URL uses HTTP instead of HTTPS",                 Recommendation = "Use HTTPS for all external service communications"             });         }                  return issues;     }      private IEnumerable<SecurityIssue> CheckExposedEndpoints()     {         var issues = new List<SecurityIssue>();                  if (_environment.IsProduction())         {             var enableSwagger = _configuration.GetValue<bool>("Features:EnableSwagger");             if (enableSwagger)             {                 issues.Add(new SecurityIssue                 {                     Type = "Exposed Development Tool",                     Severity = SecuritySeverity.Medium,                     Message = "Swagger is enabled in production environment",                     Recommendation = "Disable Swagger in production for security"                 });             }         }                  return issues;     }      private IEnumerable<SecurityIssue> CheckCorsSettings()     {         var issues = new List<SecurityIssue>();                  var corsOrigins = _configuration.GetSection("Security:Cors:AllowedOrigins").Get<string[]>();         if (corsOrigins != null && corsOrigins.Contains("*"))         {             issues.Add(new SecurityIssue             {                 Type = "Overly Permissive CORS",                 Severity = SecuritySeverity.High,                 Message = "CORS policy allows all origins (*)",                 Recommendation = "Restrict CORS to specific trusted domains"             });         }                  return issues;     }      private IEnumerable<SecurityIssue> CheckJwtSecurity()     {         var issues = new List<SecurityIssue>();                  var expiration = _configuration.GetValue<int>("Security:Jwt:ExpirationMinutes");         if (expiration > 1440) // 24 hours         {             issues.Add(new SecurityIssue             {                 Type = "Long JWT Expiration",                 Severity = SecuritySeverity.Medium,                 Message = $"JWT token expiration ({expiration} minutes) is too long",                 Recommendation = "Set JWT expiration to 15-60 minutes for better security"             });         }                  return issues;     }      private int CalculateSecurityScore(List<SecurityIssue> issues)     {         var baseScore = 100;                  foreach (var issue in issues)         {             baseScore -= issue.Severity switch             {                 SecuritySeverity.High => 20,                 SecuritySeverity.Medium => 10,                 SecuritySeverity.Low => 5,                 _ => 0             };         }                  return Math.Max(0, baseScore);     } }  public class SecurityAnalysisResult {     public List<SecurityIssue> Issues { get; set; } = new List<SecurityIssue>();     public int Score { get; set; }     public DateTime AnalyzedAt { get; set; } = DateTime.UtcNow; }  public class SecurityIssue {     public string Type { get; set; }     public SecuritySeverity Severity { get; set; }     public string Message { get; set; }     public string Recommendation { get; set; } }  public enum SecuritySeverity {     Low,     Medium,     High } 14. Troubleshooting Common Issues <a name="troubleshooting"></a> Configuration Troubleshooting Tools csharp // Comprehensive configuration diagnostics public class ConfigurationDiagnostics {     private readonly IConfiguration _configuration;     private readonly ILogger<ConfigurationDiagnostics> _logger;      public ConfigurationDiagnostics(IConfiguration configuration, ILogger<ConfigurationDiagnostics> logger)     {         _configuration = configuration;         _logger = logger;     }      public async Task<ConfigurationDiagnosticResult> RunDiagnosticsAsync()     {         var result = new ConfigurationDiagnosticResult();                  result.Issues.AddRange(await CheckConfigurationSourcesAsync());         result.Issues.AddRange(CheckRequiredSettings());         result.Issues.AddRange(CheckConfigurationValues());         result.Issues.AddRange(CheckExternalDependenciesAsync().GetAwaiter().GetResult());                  return result;     }      private async Task<List<DiagnosticIssue>> CheckConfigurationSourcesAsync()     {         var issues = new List<DiagnosticIssue>();                  // Check if appsettings files exist         var expectedFiles = new[] { "appsettings.json", $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json" };                  foreach (var file in expectedFiles)         {             if (!File.Exists(file))             {                 issues.Add(new DiagnosticIssue                 {                     Level = DiagnosticLevel.Warning,                     Category = "Configuration Files",                     Message = $"Configuration file '{file}' not found",                     Details = "This file is optional but recommended for environment-specific settings"                 });             }         }                  // Check environment variables         var requiredEnvVars = new[] { "ASPNETCORE_ENVIRONMENT" };         foreach (var envVar in requiredEnvVars)         {             if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envVar)))             {                 issues.Add(new DiagnosticIssue                 {                     Level = DiagnosticLevel.Warning,                     Category = "Environment Variables",                     Message = $"Environment variable '{envVar}' is not set",                     Details = "Defaulting to 'Production' environment"                 });             }         }                  return issues;     }      private List<DiagnosticIssue> CheckRequiredSettings()     {         var issues = new List<DiagnosticIssue>();                  var requiredSettings = new[]         {             "ConnectionStrings:DefaultConnection",             "Security:Jwt:SecretKey",             "Security:Jwt:Issuer",             "Security:Jwt:Audience"         };                  foreach (var setting in requiredSettings)         {             var value = _configuration[setting];             if (string.IsNullOrEmpty(value))             {                 issues.Add(new DiagnosticIssue                 {                     Level = DiagnosticLevel.Error,                     Category = "Required Settings",                     Message = $"Required configuration setting '{setting}' is missing or empty",                     Details = "This will cause application startup to fail"                 });             }         }                  return issues;     }      private List<DiagnosticIssue> CheckConfigurationValues()     {         var issues = new List<DiagnosticIssue>();                  // Check numeric values         var dbTimeout = _configuration.GetValue<int>("Database:Timeout", 0);         if (dbTimeout <= 0)         {             issues.Add(new DiagnosticIssue             {                 Level = DiagnosticLevel.Warning,                 Category = "Configuration Values",                 Message = "Database timeout is not set or invalid",                 Details = "Using default timeout of 30 seconds"             });         }                  // Check URL formats         var paymentUrl = _configuration["PaymentGateway:BaseUrl"];         if (!string.IsNullOrEmpty(paymentUrl) && !Uri.IsWellFormedUriString(paymentUrl, UriKind.Absolute))         {             issues.Add(new DiagnosticIssue             {                 Level = DiagnosticLevel.Error,                 Category = "Configuration Values",                 Message = "Payment gateway URL is not a valid URI",                 Details = "This will cause payment operations to fail"             });         }                  return issues;     }      private async Task<List<DiagnosticIssue>> CheckExternalDependenciesAsync()     {         var issues = new List<DiagnosticIssue>();                  // Check database connectivity         var connectionString = _configuration.GetConnectionString("DefaultConnection");         if (!string.IsNullOrEmpty(connectionString))         {             try             {                 await using var connection = new SqlConnection(connectionString);                 await connection.OpenAsync();                 await connection.CloseAsync();             }             catch (Exception ex)             {                 issues.Add(new DiagnosticIssue                 {                     Level = DiagnosticLevel.Error,                     Category = "External Dependencies",                     Message = "Cannot connect to database",                     Details = $"Database connection failed: {ex.Message}"                 });             }         }                  return issues;     } }  public class ConfigurationDiagnosticResult {     public List<DiagnosticIssue> Issues { get; set; } = new List<DiagnosticIssue>();     public DateTime DiagnosedAt { get; set; } = DateTime.UtcNow;     public bool HasErrors => Issues.Any(i => i.Level == DiagnosticLevel.Error); }  public class DiagnosticIssue {     public DiagnosticLevel Level { get; set; }     public string Category { get; set; }     public string Message { get; set; }     public string Details { get; set; } }  public enum DiagnosticLevel {     Information,     Warning,     Error }  // Configuration debugging middleware public class ConfigurationDebugMiddleware {     private readonly RequestDelegate _next;     private readonly IConfiguration _configuration;     private readonly ILogger<ConfigurationDebugMiddleware> _logger;      public ConfigurationDebugMiddleware(         RequestDelegate next,         IConfiguration configuration,         ILogger<ConfigurationDebugMiddleware> logger)     {         _next = next;         _configuration = configuration;         _logger = logger;     }      public async Task InvokeAsync(HttpContext context)     {         // Only enable in development         if (context.Request.Query.ContainsKey("debug-config"))         {             await WriteConfigurationDebugInfo(context);             return;         }          await _next(context);     }      private async Task WriteConfigurationDebugInfo(HttpContext context)     {         context.Response.ContentType = "application/json";                  var debugInfo = new         {             Environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"),             ConfigurationSources = GetConfigurationSources(),             AllSettings = GetAllConfigurationValues(),             EnvironmentVariables = GetRelevantEnvironmentVariables()         };                  var json = System.Text.Json.JsonSerializer.Serialize(debugInfo, new System.Text.Json.JsonSerializerOptions         {             WriteIndented = true         });                  await context.Response.WriteAsync(json);     }      private List<string> GetConfigurationSources()     {         // This would need reflection to access internal configuration providers         return new List<string>         {             "appsettings.json",             $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",             "Environment Variables",             "Command Line Arguments",             "User Secrets (Development only)"         };     }      private Dictionary<string, string> GetAllConfigurationValues()     {         var values = new Dictionary<string, string>();                  // Get all configuration values (be careful with secrets!)         foreach (var (key, value) in _configuration.AsEnumerable())         {             if (!string.IsNullOrEmpty(key) && !IsSensitiveKey(key))             {                 values[key] = value;             }         }                  return values;     }      private Dictionary<string, string> GetRelevantEnvironmentVariables()     {         var envVars = new Dictionary<string, string>();                  var relevantVars = Environment.GetEnvironmentVariables()             .Cast<System.Collections.DictionaryEntry>()             .Where(e => e.Key.ToString().StartsWith("ASPNETCORE_") ||                         e.Key.ToString().StartsWith("TECHMART_"))             .ToDictionary(e => e.Key.ToString(), e => e.Value.ToString());                  return relevantVars;     }      private bool IsSensitiveKey(string key)     {         var sensitiveKeywords = new[] { "password", "pwd", "secret", "key", "token", "connectionstring" };         return sensitiveKeywords.Any(keyword =>              key.Contains(keyword, StringComparison.OrdinalIgnoreCase));     } } 15. Real-World Implementation Examples <a name="real-world"></a> Enterprise-Grade Configuration Setup csharp // Complete enterprise configuration setup public class EnterpriseConfigurationBuilder {     public IHostBuilder CreateEnterpriseHostBuilder(string[] args, string applicationName)     {         return Host.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((context, config) =>             {                 var env = context.HostingEnvironment;                                  ConfigureEnterpriseAppSettings(config, env);                 ConfigureEnterpriseSecrets(config, env, applicationName);                 ConfigureEnterpriseExternalSources(config, env, applicationName);                 ConfigureEnterpriseMonitoring(config);             })             .ConfigureLogging((context, logging) =>             {                 logging.AddConfiguration(context.Configuration.GetSection("Logging"));                 logging.AddConsole();                 logging.AddDebug();                 logging.AddApplicationInsights();             })             .UseDefaultServiceProvider((context, options) =>             {                 options.ValidateScopes = context.HostingEnvironment.IsDevelopment();                 options.ValidateOnBuild = true;             });     }      private void ConfigureEnterpriseAppSettings(IConfigurationBuilder config, IHostEnvironment env)     {         // Base configuration         config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);                  // Environment-specific configuration         config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);                  // Environment-specific machine configuration (for overrides)         config.AddJsonFile($"appsettings.{env.EnvironmentName}.{Environment.MachineName}.json",              optional: true, reloadOnChange: true);     }      private void ConfigureEnterpriseSecrets(IConfigurationBuilder config, IHostEnvironment env, string applicationName)     {         if (env.IsDevelopment())         {             // User secrets for development             config.AddUserSecrets<Program>();         }         else         {             // Cloud secrets for non-development environments             var builtConfig = config.Build();                          // Azure Key Vault             var azureKeyVaultEndpoint = builtConfig["AzureKeyVault:Endpoint"];             if (!string.IsNullOrEmpty(azureKeyVaultEndpoint))             {                 config.AddAzureKeyVault(                     new Uri(azureKeyVaultEndpoint),                     new DefaultAzureCredential());             }                          // AWS Secrets Manager             var awsRegion = builtConfig["AWS:Region"];             var awsSecretName = builtConfig["AWS:Secrets:ApplicationSecretName"];             if (!string.IsNullOrEmpty(awsRegion) && !string.IsNullOrEmpty(awsSecretName))             {                 config.AddAwsSecretsManager(awsRegion, awsSecretName);             }         }     }      private void ConfigureEnterpriseExternalSources(IConfigurationBuilder config, IHostEnvironment env, string applicationName)     {         var builtConfig = config.Build();                  // Database configuration         var dbConnectionString = builtConfig.GetConnectionString("ConfigurationDb");         if (!string.IsNullOrEmpty(dbConnectionString))         {             config.AddDynamicDatabaseConfiguration(                 dbConnectionString,                 env.EnvironmentName,                 applicationName,                 reloadOnChange: true,                 reloadInterval: 60);         }                  // Consul configuration for microservices         var consulAddress = builtConfig["Consul:Address"];         if (!string.IsNullOrEmpty(consulAddress))         {             config.AddConsulKeyValue(consulAddress, $"{applicationName}/{env.EnvironmentName}");         }     }      private void ConfigureEnterpriseMonitoring(IConfigurationBuilder config)     {         // Application Insights         config.AddApplicationInsightsSettings();                  // Health check configuration         config.AddJsonFile("healthchecks.json", optional: true);     } }  // Real-world startup configuration public class EnterpriseStartup {     public EnterpriseStartup(IConfiguration configuration, IWebHostEnvironment env)     {         Configuration = configuration;         Environment = env;                  // Validate configuration on startup         ValidateConfiguration();     }      public IConfiguration Configuration { get; }     public IWebHostEnvironment Environment { get; }      private void ValidateConfiguration()     {         var validator = new EnterpriseConfigurationValidator(Configuration, Environment);         var result = validator.Validate();                  if (!result.IsValid)         {             throw new InvalidOperationException(                 $"Configuration validation failed: {string.Join(", ", result.Errors)}");         }     }      public void ConfigureServices(IServiceCollection services)     {         // Configuration validation         services.AddSingleton(new EnterpriseConfigurationValidator(Configuration, Environment));                  // Strongly-typed configuration         services.Configure<EnterpriseAppSettings>(Configuration);         services.Configure<DatabaseSettings>(Configuration.GetSection("Database"));         services.Configure<SecuritySettings>(Configuration.GetSection("Security"));         services.Configure<ExternalServicesSettings>(Configuration.GetSection("ExternalServices"));                  // Configuration-based service registration         ConfigureDatabaseServices(services);         ConfigureSecurityServices(services);         ConfigureExternalServices(services);         ConfigureApplicationServices(services);                  // Health checks         services.AddHealthChecks()             .AddSqlServer(Configuration.GetConnectionString("DefaultConnection"))             .AddUrlGroup(new Uri(Configuration["ExternalServices:PaymentGateway:HealthCheck"]))             .AddApplicationInsightsPublisher();                  // Caching         ConfigureCaching(services);     }      private void ConfigureDatabaseServices(IServiceCollection services)     {         var databaseSettings = Configuration.GetSection("Database").Get<DatabaseSettings>();                  services.AddDbContext<ApplicationDbContext>(options =>         {             options.UseSqlServer(databaseSettings.ConnectionString, sqlOptions =>             {                 sqlOptions.EnableRetryOnFailure(                     maxRetryCount: databaseSettings.RetryCount,                     maxRetryDelay: TimeSpan.FromSeconds(30),                     errorNumbersToAdd: null);             });                          if (Environment.IsDevelopment())             {                 options.EnableSensitiveDataLogging();                 options.EnableDetailedErrors();             }         });     }      private void ConfigureSecurityServices(IServiceCollection services)     {         var securitySettings = Configuration.GetSection("Security").Get<SecuritySettings>();                  services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)             .AddJwtBearer(options =>             {                 options.TokenValidationParameters = new TokenValidationParameters                 {                     ValidateIssuer = true,                     ValidateAudience = true,                     ValidateLifetime = true,                     ValidateIssuerSigningKey = true,                     ValidIssuer = securitySettings.Jwt.Issuer,                     ValidAudience = securitySettings.Jwt.Audience,                     IssuerSigningKey = new SymmetricSecurityKey(                         Encoding.UTF8.GetBytes(securitySettings.Jwt.SecretKey))                 };             });                  services.AddAuthorization(options =>         {             options.AddPolicy("AdminOnly", policy =>                  policy.RequireRole("Administrator"));         });     }      private void ConfigureExternalServices(IServiceCollection services)     {         var externalServices = Configuration.GetSection("ExternalServices").Get<ExternalServicesSettings>();                  // Configure HTTP clients with retry policies         services.AddHttpClient<IPaymentService, PaymentService>(client =>         {             client.BaseAddress = new Uri(externalServices.PaymentGateway.BaseUrl);             client.DefaultRequestHeaders.Add("X-API-Key", externalServices.PaymentGateway.ApiKey);         })         .AddPolicyHandler(GetRetryPolicy())         .AddPolicyHandler(GetCircuitBreakerPolicy());                  services.AddHttpClient<IEmailService, EmailService>(client =>         {             client.BaseAddress = new Uri(externalServices.EmailService.BaseUrl);         })         .AddPolicyHandler(GetRetryPolicy());     }      private void ConfigureApplicationServices(IServiceCollection services)     {         services.AddControllers();         services.AddSwaggerGen(c =>         {             c.SwaggerDoc("v1", new OpenApiInfo { Title = "Enterprise API", Version = "v1" });         });                  // Feature flags         var featureSettings = Configuration.GetSection("Features").Get<FeatureSettings>();         if (featureSettings.EnableCaching)         {             services.AddMemoryCache();         }                  if (featureSettings.EnableBackgroundServices)         {             services.AddHostedService<DataSyncService>();             services.AddHostedService<CleanupService>();         }     }      private void ConfigureCaching(IServiceCollection services)     {         var cacheSettings = Configuration.GetSection("Cache").Get<CacheSettings>();                  if (cacheSettings.Type == "Redis")         {             services.AddStackExchangeRedisCache(options =>             {                 options.Configuration = cacheSettings.RedisConnection;                 options.InstanceName = cacheSettings.InstanceName;             });         }         else         {             services.AddDistributedMemoryCache();         }     }      private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()     {         return HttpPolicyExtensions             .HandleTransientHttpError()             .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.TooManyRequests)             .WaitAndRetryAsync(                 retryCount: 3,                 sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),                 onRetry: (outcome, timespan, retryCount, context) =>                 {                     // Log retry attempts                 });     }      private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()     {         return HttpPolicyExtensions             .HandleTransientHttpError()             .CircuitBreakerAsync(                 handledEventsAllowedBeforeBreaking: 3,                 durationOfBreak: TimeSpan.FromSeconds(30));     }      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)     {         if (env.IsDevelopment())         {             app.UseDeveloperExceptionPage();             app.UseSwagger();             app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Enterprise API v1"));         }         else         {             app.UseExceptionHandler("/Error");             app.UseHsts();         }          app.UseHttpsRedirection();         app.UseRouting();                  app.UseAuthentication();         app.UseAuthorization();                  app.UseEndpoints(endpoints =>         {             endpoints.MapControllers();             endpoints.MapHealthChecks("/health");         });                  // Configuration diagnostics endpoint (development only)         if (env.IsDevelopment())         {             app.UseMiddleware<ConfigurationDebugMiddleware>();         }     } }  // Enterprise configuration classes public class EnterpriseAppSettings {     public string ApplicationName { get; set; }     public string Version { get; set; }     public string Environment { get; set; }     public FeatureSettings Features { get; set; }     public CacheSettings Cache { get; set; } }  public class FeatureSettings {     public bool EnableCaching { get; set; }     public bool EnableBackgroundServices { get; set; }     public bool EnableApiVersioning { get; set; }     public bool EnableResponseCompression { get; set; } }  public class CacheSettings {     public string Type { get; set; }     public string RedisConnection { get; set; }     public string InstanceName { get; set; }     public int DefaultExpiration { get; set; } = 3600; }  public class ExternalServicesSettings {     public PaymentGatewaySettings PaymentGateway { get; set; }     public EmailServiceSettings EmailService { get; set; }     public AnalyticsServiceSettings AnalyticsService { get; set; } }  public class PaymentGatewaySettings {     public string BaseUrl { get; set; }     public string ApiKey { get; set; }     public string WebhookSecret { get; set; }     public string HealthCheck { get; set; } }  public class EnterpriseConfigurationValidator {     private readonly IConfiguration _configuration;     private readonly IWebHostEnvironment _environment;      public EnterpriseConfigurationValidator(IConfiguration configuration, IWebHostEnvironment environment)     {         _configuration = configuration;         _environment = environment;     }      public ValidationResult Validate()     {         var errors = new List<string>();                  // Validate required settings         if (string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection")))         {             errors.Add("Default database connection string is required");         }                  // Validate security settings         var jwtSecret = _configuration["Security:Jwt:SecretKey"];         if (string.IsNullOrEmpty(jwtSecret) || jwtSecret.Length < 32)         {             errors.Add("JWT secret key must be at least 32 characters long");         }                  // Validate external services         var paymentUrl = _configuration["ExternalServices:PaymentGateway:BaseUrl"];         if (string.IsNullOrEmpty(paymentUrl))         {             errors.Add("Payment gateway base URL is required");         }                  return new ValidationResult         {             IsValid = !errors.Any(),             Errors = errors         };     } }  public class ValidationResult {     public bool IsValid { get; set; }     public List<string> Errors { get; set; } = new List<string>(); } This comprehensive guide covers ASP.NET Core configuration and secrets management from basic to advanced enterprise-level scenarios. The examples provided demonstrate real-world patterns and best practices that you can adapt for your specific application needs.  Remember to always prioritize security when handling configuration, especially when dealing with secrets and sensitive information. Use secure storage solutions like Azure Key Vault or AWS Secrets Manager in production environments, and never commit secrets to source control.](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZSFbhkTMDFBExnEIUf7L8Fs0fo4Z5EH9SYbAIgRqws_umAC0r1rFwewl65uqMuGYOXlvvPAA5vDn7UQKnRzcKIK6Je1ZY-VLWE7ApP0fJCY1gRV_bFp-l0PNZ4HVZM-TraRd8DkLL_cixo43OYeNYFxAKffl8RTJQD2sM6B_yRX4hh2S4HyErEX4jQTwX/s16000/Gemini_Generated_Image_2f8pzv2f8pzv2f8p.png)
0 Comments
thanks for your comments!