using System; using System.IO; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Team.Utility { public class WritableOptions<T> : IWritableOptions<T> where T : class, new() { private readonly IOptionsMonitor<T> _options; private readonly string _section; private readonly string _file; public WritableOptions(IOptionsMonitor<T> options, string section, string file) { _options = options; _section = section; _file = file; } public T Value => _options.CurrentValue; public T Get(string name) => _options.Get(name); public void Update(Action<T> applyChanges) { var physicalPath =Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _file); var jObject = JsonConvert.DeserializeObject<JObject>(File.ReadAllText(physicalPath)); var sectionObject = jObject.TryGetValue(_section, out var section) ? JsonConvert.DeserializeObject<T>(section.ToString()) : Value ?? new T(); applyChanges(sectionObject); jObject[_section] = JObject.Parse(JsonConvert.SerializeObject(sectionObject)); File.WriteAllText(physicalPath, JsonConvert.SerializeObject(jObject, Formatting.Indented),System.Text.Encoding.UTF8); } } public static class ServiceCollectionExtensions { public static void ConfigureWritable<T>( this IServiceCollection services, IConfigurationSection section, string file = "appsettings.json") where T : class, new() { services.Configure<T>(section); services.AddSingleton<IWritableOptions<T>>(provider => { var options = provider.GetService<IOptionsMonitor<T>>(); return new WritableOptions<T>(options, section.Key, file); }); } } }