How to update values into appsetting.json?

前端 未结 4 2123
半阙折子戏
半阙折子戏 2020-11-27 12:39

I am using the IOptions pattern as described in the official documentation.

This works fine when I am reading values from appsetting.json,

4条回答
  •  夕颜
    夕颜 (楼主)
    2020-11-27 13:28

    Simplified version of Matze's answer:

    public interface IWritableOptions : IOptionsSnapshot where T : class, new()
    {
        void Update(Action applyChanges);
    }
    
    public class WritableOptions : IWritableOptions where T : class, new()
    {
        private readonly IHostingEnvironment _environment;
        private readonly IOptionsMonitor _options;
        private readonly string _section;
        private readonly string _file;
    
        public WritableOptions(
            IHostingEnvironment environment,
            IOptionsMonitor options,
            string section,
            string file)
        {
            _environment = environment;
            _options = options;
            _section = section;
            _file = file;
        }
    
        public T Value => _options.CurrentValue;
        public T Get(string name) => _options.Get(name);
    
        public void Update(Action applyChanges)
        {
            var fileProvider = _environment.ContentRootFileProvider;
            var fileInfo = fileProvider.GetFileInfo(_file);
            var physicalPath = fileInfo.PhysicalPath;
    
            var jObject = JsonConvert.DeserializeObject(File.ReadAllText(physicalPath));
            var sectionObject = jObject.TryGetValue(_section, out JToken section) ?
                JsonConvert.DeserializeObject(section.ToString()) : (Value ?? new T());
    
            applyChanges(sectionObject);
    
            jObject[_section] = JObject.Parse(JsonConvert.SerializeObject(sectionObject));
            File.WriteAllText(physicalPath, JsonConvert.SerializeObject(jObject, Formatting.Indented));
        }
    }
    
    public static class ServiceCollectionExtensions
    {
        public static void ConfigureWritable(
            this IServiceCollection services,
            IConfigurationSection section,
            string file = "appsettings.json") where T : class, new()
        {
            services.Configure(section);
            services.AddTransient>(provider =>
            {
                var environment = provider.GetService();
                var options = provider.GetService>();
                return new WritableOptions(environment, options, section.Key, file);
            });
        }
    }
    

    Usage:

    services.ConfigureWritable(Configuration.GetSection("MySection"));
    

    Then:

    private readonly IWritableOptions _options;
    
    public MyClass(IWritableOptions options)
    {
        _options = options;
    }
    

    To save the changes to the file:

    _options.Update(opt => {
        opt.Field1 = "value1";
        opt.Field2 = "value2";
    });
    

    And you can pass a custom json file as optional parameter (it will use appsettings.json by default):

    services.ConfigureWritable(Configuration.GetSection("MySection"), "appsettings.custom.json");
    

提交回复
热议问题