U:调整所有代码格式
This commit is contained in:
1 parent
d133bacf55
commit
155b67e831
342 files changed
+9431
-9868
No files matched your search
@@ -24,18 +24,11 @@ public sealed class ConfigManager
|
||||
{
|
||||
var builder = new ConfigurationBuilder();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options.BasePath))
|
||||
{
|
||||
builder.SetBasePath(options.BasePath!);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(options.BasePath)) builder.SetBasePath(options.BasePath!);
|
||||
|
||||
if (options.FileProvider is not null)
|
||||
{
|
||||
builder.SetFileProvider(options.FileProvider);
|
||||
}
|
||||
if (options.FileProvider is not null) builder.SetFileProvider(options.FileProvider);
|
||||
|
||||
foreach (var src in options.Sources)
|
||||
{
|
||||
switch (src.Format)
|
||||
{
|
||||
case ConfigFormat.Json:
|
||||
@@ -46,7 +39,7 @@ public sealed class ConfigManager
|
||||
// 额外规则:将全局键复制到所有已声明的一级节中(若该节未显式定义该键),
|
||||
// 以便像 "User=..." 可同时影响 "Database:User" 这类常见节。
|
||||
var iniPath = options.BasePath is { Length: > 0 }
|
||||
? System.IO.Path.Combine(options.BasePath!, src.Path)
|
||||
? Path.Combine(options.BasePath!, src.Path)
|
||||
: src.Path;
|
||||
if (!File.Exists(iniPath))
|
||||
{
|
||||
@@ -64,7 +57,7 @@ public sealed class ConfigManager
|
||||
case ConfigFormat.Toml:
|
||||
// 解析 TOML 并以内存提供器注入(当前测试未要求 TOML 热更新)
|
||||
var tomlPath = options.BasePath is { Length: > 0 }
|
||||
? System.IO.Path.Combine(options.BasePath!, src.Path)
|
||||
? Path.Combine(options.BasePath!, src.Path)
|
||||
: src.Path;
|
||||
if (!File.Exists(tomlPath))
|
||||
{
|
||||
@@ -76,9 +69,8 @@ public sealed class ConfigManager
|
||||
var text = File.ReadAllText(tomlPath, new UTF8Encoding(false));
|
||||
var parse = Toml.Parse(text);
|
||||
if (parse.HasErrors)
|
||||
{
|
||||
throw new InvalidDataException($"Failed to load configuration from file '{tomlPath}'.", new FormatException("TOML parse failed"));
|
||||
}
|
||||
throw new InvalidDataException($"Failed to load configuration from file '{tomlPath}'.",
|
||||
new FormatException("TOML parse failed"));
|
||||
var model = parse.ToModel();
|
||||
var pairs = FlattenTomlModel(model);
|
||||
builder.AddInMemoryCollection(pairs);
|
||||
@@ -86,7 +78,6 @@ public sealed class ConfigManager
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported format: {src.Format}");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.IncludeEnvironmentVariables)
|
||||
{
|
||||
@@ -97,10 +88,7 @@ public sealed class ConfigManager
|
||||
// - 同时兼容 "APP__Name" 这类紧跟双下划线的写法(用户容易误用),通过再注册一次 "APP__" 前缀捕获
|
||||
var pfx = options.EnvironmentPrefix;
|
||||
builder.AddEnvironmentVariables(pfx);
|
||||
if (pfx.EndsWith("_"))
|
||||
{
|
||||
builder.AddEnvironmentVariables(pfx + "_");
|
||||
}
|
||||
if (pfx.EndsWith("_")) builder.AddEnvironmentVariables(pfx + "_");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -109,9 +97,7 @@ public sealed class ConfigManager
|
||||
}
|
||||
|
||||
if (options.ConfigureBuilderHook is not null)
|
||||
{
|
||||
builder = (ConfigurationBuilder)options.ConfigureBuilderHook(builder);
|
||||
}
|
||||
|
||||
var configuration = builder.Build();
|
||||
return new ConfigManager(configuration, options);
|
||||
@@ -123,27 +109,20 @@ public sealed class ConfigManager
|
||||
{
|
||||
var target = new T();
|
||||
if (string.IsNullOrWhiteSpace(section))
|
||||
{
|
||||
Configuration.Bind(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
Configuration.GetSection(section).Bind(target);
|
||||
}
|
||||
|
||||
if (validate)
|
||||
{
|
||||
ValidateObject(target, throwOnError: true);
|
||||
}
|
||||
if (validate) ValidateObject(target, true);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
public bool TryGet<T>(out T instance, string? section = null, bool validate = false) where T : new()
|
||||
{
|
||||
instance = Get<T>(section, validate: false);
|
||||
instance = Get<T>(section, false);
|
||||
if (!validate) return true;
|
||||
var results = ValidateObject(instance, throwOnError: false);
|
||||
var results = ValidateObject(instance, false);
|
||||
return results.Count == 0;
|
||||
}
|
||||
|
||||
@@ -153,10 +132,7 @@ public sealed class ConfigManager
|
||||
var visited = new HashSet<object>(ReferenceEqualityComparer.Instance);
|
||||
RecursiveValidate(instance, results, visited);
|
||||
|
||||
if (throwOnError && results.Count > 0)
|
||||
{
|
||||
throw new ConfigurationValidationException(results);
|
||||
}
|
||||
if (throwOnError && results.Count > 0) throw new ConfigurationValidationException(results);
|
||||
|
||||
return results;
|
||||
}
|
||||
@@ -170,7 +146,7 @@ public sealed class ConfigManager
|
||||
if (IsSimple(type)) return;
|
||||
|
||||
var context = new ValidationContext(instance);
|
||||
Validator.TryValidateObject(instance, context, results, validateAllProperties: true);
|
||||
Validator.TryValidateObject(instance, context, results, true);
|
||||
|
||||
foreach (var prop in type.GetProperties())
|
||||
{
|
||||
@@ -180,30 +156,27 @@ public sealed class ConfigManager
|
||||
if (IsSimple(pType)) continue;
|
||||
|
||||
if (value is System.Collections.IEnumerable enumerable && value is not string)
|
||||
{
|
||||
foreach (var item in enumerable)
|
||||
{
|
||||
if (item is null) continue;
|
||||
RecursiveValidate(item, results, visited);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RecursiveValidate(value, results, visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsSimple(Type t)
|
||||
{
|
||||
t = Nullable.GetUnderlyingType(t) ?? t;
|
||||
return t.IsPrimitive || t.IsEnum || t == typeof(string) || t == typeof(decimal) || t == typeof(DateTime) || t == typeof(Guid) || t == typeof(DateTimeOffset) || t == typeof(TimeSpan);
|
||||
return t.IsPrimitive || t.IsEnum || t == typeof(string) || t == typeof(decimal) || t == typeof(DateTime) ||
|
||||
t == typeof(Guid) || t == typeof(DateTimeOffset) || t == typeof(TimeSpan);
|
||||
}
|
||||
|
||||
// Save APIs
|
||||
public void Save<T>(T instance, string path, ConfigFormat format, bool indented = true, Encoding? encoding = null)
|
||||
{
|
||||
Directory.CreateDirectory(System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(path)) ?? ".");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)) ?? ".");
|
||||
var serializer = SerializerFactory.Get(format);
|
||||
serializer.SerializeToFile(path, instance!, indented, encoding);
|
||||
}
|
||||
@@ -247,12 +220,12 @@ public sealed class ConfigManager
|
||||
yield break;
|
||||
case TomlArray arr:
|
||||
for (var i = 0; i < arr.Count; i++)
|
||||
{
|
||||
foreach (var p in WalkValue(key + ":" + i, arr[i])) yield return p;
|
||||
}
|
||||
foreach (var p in WalkValue(key + ":" + i, arr[i]))
|
||||
yield return p;
|
||||
yield break;
|
||||
default:
|
||||
yield return new KeyValuePair<string, string?>(key, Convert.ToString(value, System.Globalization.CultureInfo.InvariantCulture));
|
||||
yield return new KeyValuePair<string, string?>(key,
|
||||
Convert.ToString(value, System.Globalization.CultureInfo.InvariantCulture));
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
@@ -275,6 +248,7 @@ public sealed class ConfigManager
|
||||
current = sections[name] = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
|
||||
continue;
|
||||
}
|
||||
|
||||
var idx = line.IndexOf('=');
|
||||
if (idx <= 0) continue;
|
||||
var key = line.Substring(0, idx).Trim();
|
||||
@@ -293,38 +267,37 @@ public sealed class ConfigManager
|
||||
foreach (var (sectionName, map) in sections)
|
||||
{
|
||||
foreach (var kv in root)
|
||||
{
|
||||
if (!map.ContainsKey(kv.Key))
|
||||
{
|
||||
yield return new KeyValuePair<string, string?>(sectionName + ":" + kv.Key, kv.Value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var kv in map)
|
||||
{
|
||||
yield return new KeyValuePair<string, string?>(sectionName + ":" + kv.Key, kv.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SerializerFactory
|
||||
{
|
||||
public static IConfigSerializer Get(ConfigFormat format) => format switch
|
||||
public static IConfigSerializer Get(ConfigFormat format)
|
||||
{
|
||||
ConfigFormat.Json => new JsonConfigSerializer(),
|
||||
ConfigFormat.Xml => new XmlConfigSerializer(),
|
||||
ConfigFormat.Ini => new IniConfigSerializer(),
|
||||
ConfigFormat.Toml => new TomlConfigSerializer(),
|
||||
_ => throw new NotSupportedException($"Unsupported format: {format}")
|
||||
};
|
||||
return format switch
|
||||
{
|
||||
ConfigFormat.Json => new JsonConfigSerializer(),
|
||||
ConfigFormat.Xml => new XmlConfigSerializer(),
|
||||
ConfigFormat.Ini => new IniConfigSerializer(),
|
||||
ConfigFormat.Toml => new TomlConfigSerializer(),
|
||||
_ => throw new NotSupportedException($"Unsupported format: {format}")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ConfigurationValidationException : Exception
|
||||
{
|
||||
public IReadOnlyList<ValidationResult> Errors { get; }
|
||||
|
||||
public ConfigurationValidationException(IReadOnlyList<ValidationResult> errors)
|
||||
: base($"Configuration validation failed: {string.Join("; ", errors.Select(e => e.ErrorMessage))}")
|
||||
{
|
||||
Errors = errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user