65 lines
2.4 KiB
C#
65 lines
2.4 KiB
C#
using Microsoft.Extensions.Configuration;
|
||
using Microsoft.Extensions.Primitives;
|
||
|
||
namespace BuildFlow.Platform.Tests;
|
||
|
||
/// 极简字典实现的 IConfiguration,仅供测试使用。
|
||
/// 完整实现 GetSection/GetChildren,让 GetValue<T> 扩展方法(走 ConfigurationBinder)能正确工作。
|
||
/// 注意:ConfigurationBinder.GetValue 内部调用 GetSection(key).Value,故必须返回有效 section。
|
||
internal sealed class DictionaryConfiguration : IConfiguration
|
||
{
|
||
private readonly Dictionary<string, string?> _values = [];
|
||
|
||
public string? this[string key]
|
||
{
|
||
get => _values.TryGetValue(key, out var v) ? v : null;
|
||
set => _values[key] = value;
|
||
}
|
||
|
||
// 支持集合初始化器语法:new DictionaryConfiguration { ["k"] = "v" }
|
||
public void Add(string key, string? value) => _values[key] = value;
|
||
|
||
IEnumerable<IConfigurationSection> IConfiguration.GetChildren() =>
|
||
_values.Select(kv => (IConfigurationSection)new LeafSection(kv.Key, kv.Value)).ToList();
|
||
|
||
IChangeToken IConfiguration.GetReloadToken() => EmptyChangeToken.Instance;
|
||
|
||
IConfigurationSection IConfiguration.GetSection(string key) =>
|
||
new LeafSection(key, _values.TryGetValue(key, out var v) ? v : null);
|
||
|
||
private sealed class LeafSection(string key, string? value) : IConfigurationSection
|
||
{
|
||
public string Key => key;
|
||
public string Path => key;
|
||
public string? Value { get; set; } = value;
|
||
|
||
string? IConfiguration.this[string childKey]
|
||
{
|
||
get => null;
|
||
set { }
|
||
}
|
||
|
||
IConfigurationSection IConfiguration.GetSection(string childKey) =>
|
||
new LeafSection($"{key}:{childKey}", null);
|
||
|
||
IEnumerable<IConfigurationSection> IConfiguration.GetChildren() => [];
|
||
|
||
IChangeToken IConfiguration.GetReloadToken() => EmptyChangeToken.Instance;
|
||
}
|
||
|
||
/// <summary>永不变更的占位 IChangeToken,避免引入额外包依赖。</summary>
|
||
private sealed class EmptyChangeToken : IChangeToken
|
||
{
|
||
public static readonly EmptyChangeToken Instance = new();
|
||
public bool ActiveChangeCallbacks => false;
|
||
public bool HasChanged => false;
|
||
public IDisposable RegisterChangeCallback(Action<object> callback, object? state) =>
|
||
new NoopDisposable();
|
||
|
||
private sealed class NoopDisposable : IDisposable
|
||
{
|
||
public void Dispose() { }
|
||
}
|
||
}
|
||
}
|