feat(data): 实现设置数据类型的动态注册和反序列化

- 添加类型注册表支持动态类型映射
- 修改LoadAllAsync方法使用注册类型进行反序列化
- 在SettingsModel初始化时自动注册数据类型到仓库
- 添加RegisterDataType接口方法支持类型注册功能
- 移除原有的无类型约束反序列化逻辑
- 增强数据加载的安全性和准确性
- [release ci]
This commit is contained in:
GeWuYou 2026-01-31 19:44:59 +08:00
parent 43dcae0cf5
commit c93d32c495
3 changed files with 37 additions and 4 deletions

View File

@ -31,4 +31,11 @@ public interface ISettingsDataRepository : IDataRepository
/// 此方法将从数据源中异步读取所有可用的设置项,并将其组织成字典格式返回
/// </remarks>
Task<IDictionary<string, IData>> LoadAllAsync();
/// <summary>
/// 注册数据类型到类型注册表中
/// </summary>
/// <param name="location">数据位置信息,用于获取键值</param>
/// <param name="type">数据类型</param>
void RegisterDataType(IDataLocation location, Type type);
}

View File

@ -32,6 +32,7 @@ public class UnifiedSettingsDataRepository(
{
private readonly SemaphoreSlim _lock = new(1, 1);
private readonly DataRepositoryOptions _options = options ?? new DataRepositoryOptions();
private readonly Dictionary<string, Type> _typeRegistry = new();
private UnifiedSettingsFile? _file;
private bool _loaded;
private IRuntimeTypeSerializer? _serializer = serializer;
@ -158,10 +159,29 @@ public class UnifiedSettingsDataRepository(
public async Task<IDictionary<string, IData>> LoadAllAsync()
{
await EnsureLoadedAsync();
return File.Sections.ToDictionary(
kv => kv.Key,
kv => Serializer.Deserialize<IData>(kv.Value)
);
var result = new Dictionary<string, IData>();
foreach (var (key, raw) in File.Sections)
{
if (!_typeRegistry.TryGetValue(key, out var type))
continue;
var data = (IData)Serializer.Deserialize(raw, type);
result[key] = data;
}
return result;
}
/// <summary>
/// 注册数据类型到类型注册表中
/// </summary>
/// <param name="location">数据位置信息,用于获取键值</param>
/// <param name="type">数据类型</param>
public void RegisterDataType(IDataLocation location, Type type)
{
_typeRegistry[location.Key] = type;
}
protected override void OnInit()

View File

@ -29,6 +29,7 @@ public class SettingsModel<TRepository>(IDataLocationProvider? locationProvider,
private readonly ConcurrentDictionary<Type, ISettingsData> _data = new();
private readonly ConcurrentDictionary<Type, Dictionary<int, ISettingsMigration>> _migrationCache = new();
private readonly ConcurrentDictionary<(Type type, int from), ISettingsMigration> _migrations = new();
private IDataLocationProvider? _locationProvider = locationProvider;
private ISettingsDataRepository? _repository = repository;
@ -215,6 +216,11 @@ public class SettingsModel<TRepository>(IDataLocationProvider? locationProvider,
{
_repository ??= this.GetUtility<TRepository>()!;
_locationProvider ??= this.GetUtility<IDataLocationProvider>()!;
foreach (var type in _data.Keys)
{
var location = _locationProvider.GetLocation(type);
DataRepository.RegisterDataType(location, type);
}
}
private ISettingsData MigrateIfNeeded(ISettingsData data)