Table of Contents

序列化器

IConfigSerializer 是读写配置的统一入口,屏蔽底层 JSON / YAML 库的差异。

支持的格式

格式 实现类 扩展名
JSON JsonConfigSerializer .json
YAML YamlConfigSerializer .yaml、.yml

两者都实现 IConfigSerializer,调用方通过接口使用,不感知具体实现。

基本用法

IConfigSerializer serializer = new JsonConfigSerializer();

// 序列化
string json = serializer.Serialize(myObject);

// 反序列化
var obj = serializer.Deserialize<MyConfig>(json);

// 从文件读
var config = serializer.DeserializeFromFile<MyConfig>("config.json");

// 写文件
serializer.SerializeToFile(myObject, "config.json");

运行时类型

当目标类型只在运行时确定时,使用非泛型重载:

Type configType = typeof(MyConfig);
object? config = serializer.Deserialize(json, configType);

添加类型转换器

自定义类型通过转换器扩展:

JSON

public sealed class GridCellConverter : JsonConverter<GridCell>
{
    public override GridCell Read(
        ref Utf8JsonReader reader,
        Type typeToConvert,
        JsonSerializerOptions options)
    {
        var text = reader.GetString()!;
        var parts = text.Split(',');
        return new GridCell(int.Parse(parts[0]), int.Parse(parts[1]));
    }

    public override void Write(
        Utf8JsonWriter writer,
        GridCell value,
        JsonSerializerOptions options)
    {
        writer.WriteStringValue($"{value.X},{value.Y}");
    }
}

serializer.AddTypeConverter(new GridCellConverter());

YAML

public sealed class GridCellConverter : IYamlTypeConverter
{
    public bool Accepts(Type type) => type == typeof(GridCell);

    public object? ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer)
    {
        var text = parser.Consume<Scalar>().Value;
        var parts = text.Split(',');
        return new GridCell(int.Parse(parts[0]), int.Parse(parts[1]));
    }

    public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer)
    {
        var cell = (GridCell)value!;
        emitter.Emit(new Scalar($"{cell.X},{cell.Y}"));
    }
}

serializer.AddTypeConverter(new GridCellConverter());

多格式工厂

IConfigSerializerFactory 按文件扩展名自动选择序列化器:

IConfigSerializerFactory factory = new ConfigSerializerFactory()
    .WithYaml();

factory.ForFile("data.json");   // → JsonConfigSerializer
factory.ForFile("data.yaml");   // → YamlConfigSerializer
factory.ForFile("data.yml");    // → YamlConfigSerializer

工厂构造时默认注册 JsonConfigSerializer 作为兜底,扩展名不匹配任何实现时使用。

异常约定

所有序列化失败都包装为 SerializationException:

try
{
    var config = serializer.DeserializeFromFile<MyConfig>("bad.json");
}
catch (SerializationException ex)
{
    // 统一处理,不用分别 catch JsonException、YamlException
    logger.Error(ex, "配置加载失败");
}

异常消息包含文件路径和位置信息(如果底层库提供)。

线程安全

  • 所有成员可并发调用
  • 读路径无锁
  • 写路径(AddTypeConverter)加锁重建,原子替换
  • 添加转换器后立即生效,正在进行的序列化不受影响