352 lines
11 KiB
C#
352 lines
11 KiB
C#
|
|
using System.ComponentModel;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Text.Json;
|
|||
|
|
|
|||
|
|
namespace WinFormsApp.Utils
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 配置文件读取工具类,支持泛型类型转换和默认值
|
|||
|
|
/// </summary>
|
|||
|
|
public static class ConfigReader
|
|||
|
|
{
|
|||
|
|
private static JsonDocument? _configDocument;
|
|||
|
|
private static readonly object _lock = new object();
|
|||
|
|
private static string _configFilePath = "appsettings.json";
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 设置配置文件路径
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="filePath">配置文件路径</param>
|
|||
|
|
public static void SetConfigPath(string filePath)
|
|||
|
|
{
|
|||
|
|
lock (_lock)
|
|||
|
|
{
|
|||
|
|
_configFilePath = filePath;
|
|||
|
|
_configDocument?.Dispose();
|
|||
|
|
_configDocument = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 加载配置文件
|
|||
|
|
/// </summary>
|
|||
|
|
private static void LoadConfig()
|
|||
|
|
{
|
|||
|
|
if (_configDocument != null) return;
|
|||
|
|
|
|||
|
|
lock (_lock)
|
|||
|
|
{
|
|||
|
|
if (_configDocument != null) return;
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (!File.Exists(_configFilePath))
|
|||
|
|
{
|
|||
|
|
Console.WriteLine($"配置文件不存在: {_configFilePath}");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
string jsonString = File.ReadAllText(_configFilePath);
|
|||
|
|
_configDocument = JsonDocument.Parse(jsonString);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Console.WriteLine($"加载配置文件失败: {ex.Message}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取配置值(泛型方法)
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="T">目标类型</typeparam>
|
|||
|
|
/// <param name="key">配置键,支持嵌套路径,如 "Module:Pattern"</param>
|
|||
|
|
/// <param name="defaultValue">默认值</param>
|
|||
|
|
/// <returns>配置值或默认值</returns>
|
|||
|
|
public static T GetValue<T>(string key, T defaultValue = default(T))
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
LoadConfig();
|
|||
|
|
|
|||
|
|
if (_configDocument == null)
|
|||
|
|
{
|
|||
|
|
return defaultValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
JsonElement element = _configDocument.RootElement;
|
|||
|
|
string[] keys = key.Split(':');
|
|||
|
|
|
|||
|
|
// 遍历嵌套路径
|
|||
|
|
foreach (string k in keys)
|
|||
|
|
{
|
|||
|
|
if (!element.TryGetProperty(k, out element))
|
|||
|
|
{
|
|||
|
|
return defaultValue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return ConvertValue<T>(element, defaultValue);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Console.WriteLine($"读取配置 '{key}' 时出错: {ex.Message}");
|
|||
|
|
return defaultValue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取字符串配置值
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="key">配置键</param>
|
|||
|
|
/// <param name="defaultValue">默认值</param>
|
|||
|
|
/// <returns>字符串值</returns>
|
|||
|
|
public static string GetString(string key, string defaultValue = "")
|
|||
|
|
{
|
|||
|
|
return GetValue(key, defaultValue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取整数配置值
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="key">配置键</param>
|
|||
|
|
/// <param name="defaultValue">默认值</param>
|
|||
|
|
/// <returns>整数值</returns>
|
|||
|
|
public static int GetInt(string key, int defaultValue = 0)
|
|||
|
|
{
|
|||
|
|
return GetValue(key, defaultValue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取布尔配置值
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="key">配置键</param>
|
|||
|
|
/// <param name="defaultValue">默认值</param>
|
|||
|
|
/// <returns>布尔值</returns>
|
|||
|
|
public static bool GetBool(string key, bool defaultValue = false)
|
|||
|
|
{
|
|||
|
|
return GetValue(key, defaultValue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取双精度浮点数配置值
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="key">配置键</param>
|
|||
|
|
/// <param name="defaultValue">默认值</param>
|
|||
|
|
/// <returns>双精度浮点数值</returns>
|
|||
|
|
public static double GetDouble(string key, double defaultValue = 0.0)
|
|||
|
|
{
|
|||
|
|
return GetValue(key, defaultValue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取数组配置值
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="T">数组元素类型</typeparam>
|
|||
|
|
/// <param name="key">配置键</param>
|
|||
|
|
/// <param name="defaultValue">默认值</param>
|
|||
|
|
/// <returns>数组值</returns>
|
|||
|
|
public static T[] GetArray<T>(string key, T[] defaultValue = null)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
LoadConfig();
|
|||
|
|
|
|||
|
|
if (_configDocument == null)
|
|||
|
|
{
|
|||
|
|
return defaultValue ?? new T[0];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
JsonElement element = _configDocument.RootElement;
|
|||
|
|
string[] keys = key.Split(':');
|
|||
|
|
|
|||
|
|
// 遍历嵌套路径
|
|||
|
|
foreach (string k in keys)
|
|||
|
|
{
|
|||
|
|
if (!element.TryGetProperty(k, out element))
|
|||
|
|
{
|
|||
|
|
return defaultValue ?? new T[0];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (element.ValueKind != JsonValueKind.Array)
|
|||
|
|
{
|
|||
|
|
return defaultValue ?? new T[0];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
List<T> result = new List<T>();
|
|||
|
|
foreach (JsonElement item in element.EnumerateArray())
|
|||
|
|
{
|
|||
|
|
T convertedValue = ConvertValue<T>(item, default(T));
|
|||
|
|
result.Add(convertedValue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result.ToArray();
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Console.WriteLine($"读取数组配置 '{key}' 时出错: {ex.Message}");
|
|||
|
|
return defaultValue ?? new T[0];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取复杂对象配置值
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="T">目标类型</typeparam>
|
|||
|
|
/// <param name="key">配置键</param>
|
|||
|
|
/// <param name="defaultValue">默认值</param>
|
|||
|
|
/// <returns>对象值</returns>
|
|||
|
|
public static T GetObject<T>(string key, T defaultValue = default(T)) where T : class
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
LoadConfig();
|
|||
|
|
|
|||
|
|
if (_configDocument == null)
|
|||
|
|
{
|
|||
|
|
return defaultValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
JsonElement element = _configDocument.RootElement;
|
|||
|
|
string[] keys = key.Split(':');
|
|||
|
|
|
|||
|
|
// 遍历嵌套路径
|
|||
|
|
foreach (string k in keys)
|
|||
|
|
{
|
|||
|
|
if (!element.TryGetProperty(k, out element))
|
|||
|
|
{
|
|||
|
|
return defaultValue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return JsonSerializer.Deserialize<T>(element.GetRawText()) ?? defaultValue;
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Console.WriteLine($"读取对象配置 '{key}' 时出错: {ex.Message}");
|
|||
|
|
return defaultValue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 类型转换方法
|
|||
|
|
/// </summary>
|
|||
|
|
/// <typeparam name="T">目标类型</typeparam>
|
|||
|
|
/// <param name="element">JSON元素</param>
|
|||
|
|
/// <param name="defaultValue">默认值</param>
|
|||
|
|
/// <returns>转换后的值</returns>
|
|||
|
|
private static T ConvertValue<T>(JsonElement element, T defaultValue)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
Type targetType = typeof(T);
|
|||
|
|
Type nullableType = Nullable.GetUnderlyingType(targetType);
|
|||
|
|
|
|||
|
|
// 处理可空类型
|
|||
|
|
if (nullableType != null)
|
|||
|
|
{
|
|||
|
|
if (element.ValueKind == JsonValueKind.Null)
|
|||
|
|
{
|
|||
|
|
return defaultValue;
|
|||
|
|
}
|
|||
|
|
targetType = nullableType;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理基本类型
|
|||
|
|
switch (element.ValueKind)
|
|||
|
|
{
|
|||
|
|
case JsonValueKind.String:
|
|||
|
|
if (targetType == typeof(string))
|
|||
|
|
return (T)(object)element.GetString();
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case JsonValueKind.Number:
|
|||
|
|
if (targetType == typeof(int))
|
|||
|
|
return (T)(object)element.GetInt32();
|
|||
|
|
if (targetType == typeof(long))
|
|||
|
|
return (T)(object)element.GetInt64();
|
|||
|
|
if (targetType == typeof(double))
|
|||
|
|
return (T)(object)element.GetDouble();
|
|||
|
|
if (targetType == typeof(float))
|
|||
|
|
return (T)(object)element.GetSingle();
|
|||
|
|
if (targetType == typeof(decimal))
|
|||
|
|
return (T)(object)element.GetDecimal();
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case JsonValueKind.True:
|
|||
|
|
case JsonValueKind.False:
|
|||
|
|
if (targetType == typeof(bool))
|
|||
|
|
return (T)(object)element.GetBoolean();
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case JsonValueKind.Null:
|
|||
|
|
return defaultValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 使用TypeConverter进行转换
|
|||
|
|
TypeConverter converter = TypeDescriptor.GetConverter(targetType);
|
|||
|
|
if (converter.CanConvertFrom(typeof(string)))
|
|||
|
|
{
|
|||
|
|
string stringValue = element.GetRawText().Trim('"');
|
|||
|
|
return (T)converter.ConvertFromString(stringValue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 尝试JSON反序列化
|
|||
|
|
return JsonSerializer.Deserialize<T>(element.GetRawText()) ?? defaultValue;
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Console.WriteLine($"类型转换失败: {ex.Message}");
|
|||
|
|
return defaultValue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 检查配置键是否存在
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="key">配置键</param>
|
|||
|
|
/// <returns>如果存在返回true,否则返回false</returns>
|
|||
|
|
public static bool HasKey(string key)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
LoadConfig();
|
|||
|
|
|
|||
|
|
if (_configDocument == null)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
JsonElement element = _configDocument.RootElement;
|
|||
|
|
string[] keys = key.Split(':');
|
|||
|
|
|
|||
|
|
foreach (string k in keys)
|
|||
|
|
{
|
|||
|
|
if (!element.TryGetProperty(k, out element))
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
catch
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 释放资源
|
|||
|
|
/// </summary>
|
|||
|
|
public static void Dispose()
|
|||
|
|
{
|
|||
|
|
lock (_lock)
|
|||
|
|
{
|
|||
|
|
_configDocument?.Dispose();
|
|||
|
|
_configDocument = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|