配置文件热重载功能

This commit is contained in:
陈淳
2022-09-15 17:09:30 +08:00
parent e535133eca
commit 489a0b6fb8
8 changed files with 139 additions and 2 deletions

View File

@@ -16,14 +16,14 @@ namespace Yi.Framework.WebCore.BuilderExtend
string[] myJsonFile = new string[] { "appsettings.json", "Config/configuration.json" };
foreach (var item in myJsonFile)
{
builder.AddJsonFile(item, optional: true, reloadOnChange: false);
builder.AddJsonFile(item, optional: true, reloadOnChange: true);
}
}
else
{
foreach (var item in JsonFile)
{
builder.AddJsonFile(item, optional: true, reloadOnChange: false);
builder.AddJsonFile(item, optional: true, reloadOnChange: true);
}
}

View File

@@ -0,0 +1,14 @@

using Microsoft.Extensions.Options;
namespace Yi.Framework.WebCore.BuilderExtend.OptionsWritable;
public abstract class FileOptionsWritableBase<TOptions> : OptionsWritableBase<TOptions>, IOptionsWritable<TOptions> where TOptions : class, new()
{
public FileOptionsWritableBase(IOptionsMonitor<TOptions> options, string section, string fileName) : base(options, section)
{
this.FileName = fileName;
}
public string FileName { get; }
}

View File

@@ -0,0 +1,10 @@

using Microsoft.Extensions.Options;
using System;
namespace Yi.Framework.WebCore.BuilderExtend.OptionsWritable;
public interface IOptionsWritable<out TOptions> : IOptionsSnapshot<TOptions> where TOptions : class, new()
{
void Update(Action<TOptions> configuration);
}

View File

@@ -0,0 +1,37 @@
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
namespace Yi.Framework.WebCore.BuilderExtend.OptionsWritable.Internal;
internal class JsonOptionsWritable<TOptions> : FileOptionsWritableBase<TOptions>, IOptionsWritable<TOptions> where TOptions : class, new()
{
public JsonOptionsWritable(IOptionsMonitor<TOptions> options, string section, string fileName) : base(options, section, fileName)
{
}
public override void Update(Action<TOptions> configuration)
{
JObject? jObject = JsonConvert.DeserializeObject<JObject>(File.ReadAllText(this.FileName));
if (jObject != null)
{
TOptions option = this.Monitor.CurrentValue ?? new TOptions();
if (jObject.TryGetValue(this.Section, out JToken? jtoken))
{
option = JsonConvert.DeserializeObject<TOptions>(jtoken.ToString()) ?? new TOptions();
configuration?.Invoke(option);
jObject[this.Section] = JObject.Parse(JsonConvert.SerializeObject(option));
}
else
{
configuration?.Invoke(option);
jObject.TryAdd(this.Section, JObject.Parse(JsonConvert.SerializeObject(option)));
}
File.WriteAllText(this.FileName, JsonConvert.SerializeObject(jObject, Formatting.Indented));
}
}
}

View File

@@ -0,0 +1,29 @@

using Microsoft.Extensions.Options;
using System;
namespace Yi.Framework.WebCore.BuilderExtend.OptionsWritable;
public abstract class OptionsWritableBase<TOptions> : IOptionsWritable<TOptions> where TOptions : class, new()
{
public OptionsWritableBase(
IOptionsMonitor<TOptions> options,
string section)
{
this.Monitor = options;
this.Section = section;
}
public IOptionsMonitor<TOptions> Monitor { get; }
public string Section { get; }
public TOptions Value => this.Monitor.CurrentValue ?? new TOptions();
public TOptions Get(string name)
{
return this.Monitor.Get(name);
}
public abstract void Update(Action<TOptions> configuration);
}

View File

@@ -0,0 +1,41 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Configuration;
using Yi.Framework.WebCore.BuilderExtend.OptionsWritable;
using Yi.Framework.WebCore.BuilderExtend.OptionsWritable.Internal;
namespace Yi.Framework.WebCore.BuilderExtend;
public static class OptionsWritableConfigurationServiceCollectionExtensions
{
public static void ConfigureJson<TOption>(this IServiceCollection services, Microsoft.Extensions.Configuration.ConfigurationManager configuration, string jsonFilePath)
where TOption : class, new()
{
ConfigureJson<TOption>(services, configuration.GetSection(typeof(TOption).Name), jsonFilePath);
}
public static void ConfigureJson<TOption>(this IServiceCollection services, IConfigurationSection section, string jsonFilePath)
where TOption : class, new()
{
services.Configure<TOption>(section);
services.AddTransient<IOptionsWritable<TOption>>(provider =>
new JsonOptionsWritable<TOption>(provider.GetRequiredService<IOptionsMonitor<TOption>>(), section.Key, jsonFilePath));
}
public static void ConfigureJson<TOption>(this IServiceCollection services, Microsoft.Extensions.Configuration.ConfigurationManager configuration, Func<IServiceProvider, string> jsonFilePathFunc)
where TOption : class, new()
{
ConfigureJson<TOption>(services, configuration.GetSection(typeof(TOption).Name), jsonFilePathFunc);
}
public static void ConfigureJson<TOption>(this IServiceCollection services, IConfigurationSection section, Func<IServiceProvider, string> jsonFilePathFunc)
where TOption : class, new()
{
services.Configure<TOption>(section);
services.AddTransient<IOptionsWritable<TOption>>(provider =>
new JsonOptionsWritable<TOption>(provider.GetRequiredService<IOptionsMonitor<TOption>>(), section.Key, jsonFilePathFunc.Invoke(provider)));
}
}