2025-11-08 15:10:44 +08:00

128 lines
3.6 KiB
C#

using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace BangumiRenamer.Utils;
public class ConfigItemAttribute : System.Attribute
{
public string Name;
public ConfigItemAttribute(string name)
{
Name = name;
}
}
public interface IConfigItem;
public class Config(string configPath)
{
private static readonly Lazy<Config> _lazy = new (() =>
{
var config = new Config("config.json");
config.ReLoad();
return config;
});
public static Config Default => _lazy.Value;
private static readonly Dictionary<Type, string> Cache = new();
private readonly Dictionary<string, object> _configObjects = new();
private readonly Dictionary<string, JObject> _configs = new();
private static string GetConfigItemName(Type type)
{
if (Cache.TryGetValue(type, out var name)) return name;
name = type.Name;
if(type.GetCustomAttribute(typeof(ConfigItemAttribute)) is ConfigItemAttribute info)
{
name = string.IsNullOrEmpty(info.Name) ? type.Name : info.Name;
}
Cache[type] = name;
return name;
}
public T Get<T>() where T : class, IConfigItem, new()
{
var name = GetConfigItemName(typeof(T));
if (_configObjects.TryGetValue(name, out var value))
{
return (T) value;
}
T result;
if (_configs.TryGetValue(name, out var jObject))
{
result = jObject.ToObject<T>();
}
else
{
result = new T();
}
_configObjects[name] = result;
return result;
}
public void Reset<T>() where T : class, IConfigItem, new()
{
var name = GetConfigItemName(typeof(T));
_configs.Remove(name);
_configObjects.Remove(name);
}
public void Clear()
{
_configs.Clear();
_configObjects.Clear();
}
public void ReLoad()
{
_configs.Clear();
_configObjects.Clear();
if (!File.Exists(configPath)) return;
var configJson = File.ReadAllText(configPath);
var config = JObject.Parse(configJson);
foreach (var kv in config)
{
_configs[kv.Key] = kv.Value.ToObject<JObject>();
}
}
public void Save()
{
foreach (var config in _configObjects)
{
_configs[config.Key] = JObject.FromObject(config.Value);
}
File.WriteAllText(configPath, JsonConvert.SerializeObject(_configs, Formatting.Indented));
}
public static void CreateEmptyConfig()
{
var configItemTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly =>
{
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException)
{
return Array.Empty<Type>();
}
})
.Where(type => type.IsClass &&
!type.IsAbstract &&
typeof(IConfigItem).IsAssignableFrom(type))
.ToList();
var configs = new Dictionary<string, JObject>();
foreach (var type in configItemTypes)
{
var name = GetConfigItemName(type);
configs[name] = JObject.FromObject(Activator.CreateInstance(type));
}
File.WriteAllText("config_default.json", JsonConvert.SerializeObject(configs, Formatting.Indented));
}
}