YamlDotNet - 如何在对象更新后处理版本控制?

问题描述 投票:0回答:1

我在我的项目中使用 YamlDotNet 已经有一段时间了,不过随着其中一个项目的不断发展,我可以利用您的帮助来解决我面临的以下问题。

想象一下我已经序列化以下对象一段时间了(我会让一切尽可能简单):

[YamlSerializable]
public class Trip
{
    [YamlMember]
    public string Name { get; set; }

    [YamlMember]
    public int[] BreakTimestamps { get; set; }
}

BreakTimestamps
是从行程开始算起的时间戳(以秒为单位)。

现在,假设我为过去几年的旅行收集了相当多的序列化对象(在文件中)。

我的项目不断发展,我想收集更多有关旅行的信息,因此我将我的

Trip
课程更新为以下内容:

[YamlSerializable]
public class Trip
{
    [Flags]
    public enum BreakType
    {
        Undefined = 0,
        Nutrition = 1 << 0,
        Sanitary = 1 << 1,
        Mechanical = 1 << 2,
        Sightseeing = 1 << 3,
        Other = 1 << (sizeof(int) - 1)
    }

    [YamlSerializable]
    public class Break
    {
        [YamlMember]
        public int Timestamp { get; set; }

        [YamlMember]
        public int Duration { get; set; }

        [YamlMember]
        public BreakType Reason { get; set; }
    }

    [YamlMember]
    public string Name { get; set; }

    [YamlMember]
    public Break[] Breaks { get; set; }
}

我面临的问题是,如果我使用新类来反序列化现有文件,我将不会获得有关时间戳的任何信息。 我想要实现的是,如果我反序列化以前的版本,对于

BreakTimestamps
中的每个元素,我将创建一个新的
Break
对象并仅填充
Timestamp
属性,因此我将逐渐更新所有以前的版本对象。

您对如何解决这个问题有什么想法吗?

我看到以下可能性:

  • 在更新版本中也保留
    BreakTimestamps
    属性以实现向后兼容性,但这会在每个新序列化的对象中创建冗余信息
  • 添加定义类版本号的属性,将更新的类命名为
    Trip_V2.0
    ,使用忽略不匹配属性的反序列化器 (
    var deserializer = (Deserializer)new DeserializerBuilder().IgnoreUnmatchedProperties().Build();
    ),检查版本并使用相应的目标进行反序列化(
    <Trip>
    <Trip_V2.0>

如有其他想法,我将不胜感激。 对于最优雅的解决方案,让我们假设这不是该对象类的最后一次更新,我希望有未来更新的可能性。

感谢您的任何建议。

object serialization deserialization versioning yamldotnet
1个回答
0
投票

当您的代码发生这样的重大更改时,您通常会对数据运行一次性升级,将旧格式转换为新格式。

如果您使用 YAML、某些其他文件格式或某种数据库,这也是一样的。

© www.soinside.com 2019 - 2024. All rights reserved.