CSharp Configuration Handling
Introduction
Struggled with the right way to do configuration as there were two approaches so thought I would right down the one that works for me in 2025
Example Redis Service
Create a Config to hold the Setting
namespace Infrastructure.Caching.Configuration;
using Domain.Interfaces.Configuration;
public class CacheOptions : ICacheConfig
{
public required string Host { get; set; }
public required int Port { get; set; }
public required string Password { get; set; }
public string InstanceName { get; set; } = "DvdrentalApi_";
public TimeSpan DefaultTtl { get; set; } = TimeSpan.FromMinutes(5);
public string ConnectionString => $"{Host}:{Port},password={Password},ssl=False,abortConnect=False";
}
Create a Service to do it
namespace Infrastructure.Caching.Services;
using System.Text.Json;
using Domain.Interfaces.Caching;
using Domain.Interfaces.Configuration;
using Microsoft.Extensions.Caching.Distributed;
public class RedisCacheService(IDistributedCache cache, ICacheConfig config) : ICacheService
{
private readonly IDistributedCache _cache = cache;
private readonly ICacheConfig _config = config;
public async Task<T?> GetAsync<T>(string key, CancellationToken ct = default)
{
var namespacedKey = $"{_config.InstanceName}{key}";
var cached = await _cache.GetStringAsync(namespacedKey, ct);
return cached is null ? default : JsonSerializer.Deserialize<T>(cached);
}
public async Task SetAsync<T>(string key, T value, TimeSpan? ttl = null, CancellationToken ct = default)
{
var namespacedKey = $"{_config.InstanceName}{key}";
var serialized = JsonSerializer.Serialize(value);
await _cache.SetStringAsync(
namespacedKey,
serialized,
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = ttl ?? _config.DefaultTtl
},
ct);
}
public Task RemoveAsync(string key, CancellationToken ct = default)
{
var namespacedKey = $"{_config.InstanceName}{key}";
return _cache.RemoveAsync(namespacedKey, ct);
}
}
Add IServiceCollection Extension for Startup
public static IServiceCollection AddCachingService(this IServiceCollection services, IConfiguration config)
{
// Read Cache Options from appsettings.json
services.Configure<CacheOptions>(config.GetSection("Cache"));
// Register ICacheConfig for DI
services.AddSingleton<ICacheConfig>(sp => sp.GetRequiredService<IOptions<CacheOptions>>().Value);
// Register Redis as IDistributedCache
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = config["Cache:ConnectionString"];
options.InstanceName = config["Cache:InstanceName"];
});
// Register RedisCacheService
services.AddSingleton<ICacheService, RedisCacheService>();
return services;
}
Make an appsetting.json
Here is my example appsetting.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"System.Net.Http": "Warning",
"Microsoft": "Warning",
"Microsoft.AspNetCore": "Warning"
}
},
"Cache": {
"ConnectionString": "localhost:6379",
"InstanceName": "DvdrentalApi_"
}
}