配置文件热重载功能
This commit is contained in:
@@ -10,6 +10,8 @@ using Microsoft.Extensions.Localization;
|
|||||||
using Yi.Framework.WebCore.AttributeExtend;
|
using Yi.Framework.WebCore.AttributeExtend;
|
||||||
using Yi.Framework.WebCore.SignalRHub;
|
using Yi.Framework.WebCore.SignalRHub;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
builder.Configuration.AddCommandLine(args);
|
builder.Configuration.AddCommandLine(args);
|
||||||
builder.WebHost.UseUrls(builder.Configuration.GetValue<string>("StartUrl"));
|
builder.WebHost.UseUrls(builder.Configuration.GetValue<string>("StartUrl"));
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ namespace Yi.Framework.WebCore.BuilderExtend
|
|||||||
string[] myJsonFile = new string[] { "appsettings.json", "Config/configuration.json" };
|
string[] myJsonFile = new string[] { "appsettings.json", "Config/configuration.json" };
|
||||||
foreach (var item in myJsonFile)
|
foreach (var item in myJsonFile)
|
||||||
{
|
{
|
||||||
builder.AddJsonFile(item, optional: true, reloadOnChange: false);
|
builder.AddJsonFile(item, optional: true, reloadOnChange: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (var item in JsonFile)
|
foreach (var item in JsonFile)
|
||||||
{
|
{
|
||||||
builder.AddJsonFile(item, optional: true, reloadOnChange: false);
|
builder.AddJsonFile(item, optional: true, reloadOnChange: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,4 +37,8 @@
|
|||||||
<ProjectReference Include="..\Yi.Framework.Service\Yi.Framework.Service.csproj" />
|
<ProjectReference Include="..\Yi.Framework.Service\Yi.Framework.Service.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="BuilderExtend\OptionsWritable\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user