using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Microsoft.Extensions.Configuration; namespace Configuration.Core; public class KeyValueConfigurationBuilder { private readonly IConfigurationRepository _repository; private readonly JObject _rootObject = new(); private ConfigurationReloadToken _reloadToken = new(); private IConfiguration _configuration; public KeyValueConfigurationBuilder(IConfigurationRepository repository) { _repository = repository; } public async Task LoadConfiguration() { var configurations = await _repository.GetActiveConfigurations(); foreach (var config in configurations) { AddKeyValue(config.Key, config.Value); } OnReload(); } public void AddKeyValue(string key, string jsonValue) { var valueObject = JsonConvert.DeserializeObject(jsonValue); var parts = key.Split(':'); JObject current = _rootObject; for (int i = 0; i < parts.Length - 1; i++) { var part = parts[i]; if (!current.ContainsKey(part)) { current[part] = new JObject(); } current = (JObject)current[part]; } current[parts[^1]] = valueObject; } private void OnReload() { var previousToken = Interlocked.Exchange(ref _reloadToken, new ConfigurationReloadToken()); previousToken.OnReload(); _configuration = null; } public IConfiguration Build() => _configuration ??= new JsonConfiguration(_rootObject, _reloadToken); }