YongAnGame.ModuleLib
1.0.0-rc2
dotnet add package YongAnGame.ModuleLib --version 1.0.0-rc2
NuGet\Install-Package YongAnGame.ModuleLib -Version 1.0.0-rc2
<PackageReference Include="YongAnGame.ModuleLib" Version="1.0.0-rc2" />
<PackageVersion Include="YongAnGame.ModuleLib" Version="1.0.0-rc2" />
<PackageReference Include="YongAnGame.ModuleLib" />
paket add YongAnGame.ModuleLib --version 1.0.0-rc2
#r "nuget: YongAnGame.ModuleLib, 1.0.0-rc2"
#:package YongAnGame.ModuleLib@1.0.0-rc2
#addin nuget:?package=YongAnGame.ModuleLib&version=1.0.0-rc2&prerelease
#tool nuget:?package=YongAnGame.ModuleLib&version=1.0.0-rc2&prerelease
YongAnGame.ModuleLib
面向游戏 MOD 系统的通用模块库,提供配置加载、序列化、仓储管理等基础设施
特性
- 多种格式支持:JSON、YAML,通过统一接口
IConfigSerializer抽象,换格式不改调用方 - 格式工厂:
IConfigSerializerFactory按文件扩展名选择合适的序列化器 - 线程安全:所有公开接口承诺并发安全;仓储实现读路径无锁,写路径依赖原子操作
- 结构化标识符:
Id支持ModId.ItemId:SubId格式,内置多维度比较方法 - 面向 MOD 的配置仓储:
IConfigRepository负责目录扫描、缓存、哈希,支持Unload+Load组合实现热重载 - 日志抽象:仓储只依赖
Microsoft.Extensions.Logging.ILogger,不绑定具体日志实现 - 低框架兼容:通过 Polyfill 为
netstandard2.0等旧目标补齐新 API
项目结构
YongAnGame.ModuleLib/
├── Compatibility/ # 低框架静态扩展
├── Components/ # 通用值类型(Id 等)
├── Exceptions/ # 统一异常类型
├── Extensions/ # 扩展方法(工厂便捷入口等)
├── Features/
│ ├── Serializers/ # 序列化器实现(JSON、YAML)与工厂
│ ├── ConfigRepository # 配置仓储默认实现
│ └── ConfigOptions # 配置选项默认实现
└── Interfaces/
├── Configs/ # 配置相关接口
├── Repositories/ # 仓储相关接口
└── IHasId.cs # 带 Id 的数据对象契约
核心概念
序列化器(IConfigSerializer)
读写配置的统一入口,屏蔽底层 JSON / YAML 库差异
IReadOnlyList<string> Extensions { get; }
void AddTypeConverter(object converter);
T? Deserialize<T>(string text) where T : class;
object? Deserialize(string text, Type type);
string Serialize<T>(T value) where T : class;
T? DeserializeFromFile<T>(string filePath) where T : class;
void SerializeToFile<T>(T value, string filePath) where T : class;
所有实现遵守以下约定:
- 线程安全,所有成员均可并发调用
- 底层异常统一包装为
SerializationException - 错误消息中包含文件位置信息
- 新增转换器后立即生效,不影响正在进行的序列化
序列化器工厂(IConfigSerializerFactory)
按文件扩展名自动选择序列化器,调用方无需关心具体格式
IConfigSerializerFactory factory = new ConfigSerializerFactory()
.WithYaml();
var serializer = factory.ForFile("config.yaml"); // → YamlConfigSerializer
var jsonSerializer = factory.ForFile("config.json"); // → 默认 JSON
工厂构造时默认注册一个 JSON 序列化器作为兜底,扩展名不匹配任何已注册实现时使用
配置仓储(IConfigRepository)
从 MOD 目录加载配置并按类型分组缓存
IConfigRepository repo = new ConfigRepository(logger, options, serializer, "example_mod");
repo.Add(typeof(CharacterConfig), (typeof(CharacterData), false));
repo.Load();
if (repo.TryGetValue<CharacterConfig, CharacterData>("char_001", out var data))
{
// 使用 data
}
内部使用 ConcurrentDictionary 保存状态,加载与查询可并发进行
标准仓储(IStandardRepository<TKey, TData>)
可复用的按类型仓储抽象,只读契约由 IReadOnlyStandardRepository<TKey, TData> 提供
public interface IReadOnlyStandardRepository<TKey, TData> : IEnumerable<TData>
where TData : IHasId
{
TData? GetValue(TKey key);
bool TryGetValue(TKey key, [NotNullWhen(true)] out TData? data);
bool ContainsKey(TKey key);
}
public interface IStandardRepository<TKey, TData>
: IReadOnlyStandardRepository<TKey, TData>
where TData : IHasId
{
void Add(TData data);
bool TryAdd(TData data);
}
枚举结果是调用瞬间的快照,不因并发修改而抛异常
标识符(Id)
形如 ModId.ItemId:SubId 的结构化标识符,用于跨 MOD 引用
var id = new Id("example_mod", "char_001", subId: 0);
id.SameMod(other); // 是否同一 MOD
id.SameItem(other); // 是否同一项目(忽略 MOD)
id.SameModAndItem(other); // 同一 MOD 下的同一项目
id.SameItemAndSubId(other); // 跨 MOD 的同一项目同一序号
id.SameAll(other); // 完全相等
SubId省略时按 0 处理,a.b与a.b:0表示同一个 Id- 实现了
IParsable<Id>,可在泛型约束中统一处理 - 不可变值类型,天然线程安全
多目标框架兼容
项目同时支持现代框架与旧框架,通过三类工具补齐缺失的 API:
| 工具 | 职责 | 覆盖内容 |
|---|---|---|
| Polyfill(SimonCropp) | BCL API 补齐 | KeyValuePair.Deconstruct、HashData 等 |
| Microsoft.Bcl.HashCode | 官方兼容包 | HashCode.Combine 等 |
| 本项目 Compatibility 文件 | 项目自维护 | ThrowIfXxx 静态扩展、CallerArgumentExpression(如未由 Polyfill 提供) |
调用点代码无需条件编译,例如下面写法在所有目标框架下均能通过:
ArgumentException.ThrowIfNullOrWhiteSpace(modId);
ArgumentOutOfRangeException.ThrowIfNegative(subId);
低版本走 Compatibility 中的静态扩展,高版本走 BCL 内置实现
环境要求
- 核心库:
.NET 9.0或更高(使用了System.Threading.Lock) - 多目标兼容:可同时编译
netstandard2.0/netstandard2.1/net48/net8.0旧框架 - C# 14 扩展成员:需要
.NET 10 SDK或支持该特性的编译器 - 推荐 IDE:Visual Studio 2026
引用项目
本库通过项目引用依赖以下子项目:
NuGet 依赖
| 依赖 | 用途 |
|---|---|
System.Text.Json |
JSON 序列化 |
YamlDotNet |
YAML 序列化 |
Microsoft.Extensions.Logging.Abstractions |
日志 |
Polyfill |
低框架 BCL API Polyfill |
Microsoft.Bcl.HashCode |
HashCode 兼容 |
System.Memory |
数组切片与 Span 支持 |
MinVer |
版本管理 |
线程安全模型
所有公开接口均承诺线程安全,实现统一采用不可变快照替换:
- 读路径无锁:
volatile字段直接读取,零开销 - 写路径加锁:
Lock保护“构建新状态 + 原子替换” - 旧状态对读者始终可用:读者要么拿到旧快照、要么拿到新快照,不会看到半成品
- 枚举为快照语义:
foreach看到的是进入循环那一刻的内容,不因并发修改抛异常
具体实现细节见各接口的 XML 注释
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 is compatible. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7
- Microsoft.Bcl.HashCode (>= 6.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.14)
- System.Text.Json (>= 10.0.12)
- YamlDotNet (>= 18.1.0)
-
.NETStandard 2.0
- Microsoft.Bcl.HashCode (>= 6.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.14)
- System.Text.Json (>= 10.0.12)
- YamlDotNet (>= 18.1.0)
-
.NETStandard 2.1
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.14)
- System.Text.Json (>= 10.0.12)
- YamlDotNet (>= 18.1.0)
-
net10.0
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.14)
- YamlDotNet (>= 18.1.0)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.14)
- YamlDotNet (>= 18.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-rc2 | 62 | 10/30/2026 |