【问题标题】:Simple data file versioning with DataContractSerializer使用 DataContractSerializer 进行简单的数据文件版本控制
【发布时间】:2009-10-03 12:12:45
【问题描述】:

阅读Data Contract Versioning 后,我们得出结论,这并不是故事的全部。例如,如果您以前有 ValueA,而在新版本中它现在称为 ValueB 并且属于不同类型,您需要将 ValueA 转换为 ValueB,会发生什么?

我可以使用一些 callbacks 来帮助解决这个问题,但如果我们期望格式在很长一段时间内频繁更改,它看起来不是一个非常易于维护的解决方案。

我们确定的解决方案是保留“按版本保存”字段,并在加载文件时根据需要调用特定于旧版本的转换例程。这些转换例程知道如何将旧数据的 XML 转换为新数据的 XML。

然而,事实证明,DataContractSerializes requires the order of the elements to be exactly what it expects。这意味着我们的转换过程必须知道将元素插入到准确正确的位置。如果考虑到继承,这比简单地添加具有已知名称的元素要困难得多。使用继承,您不能可靠地使用AddBeforeSelfAddAfterSelf any 字段,因为没有一个字段始终紧邻这个新字段。

撇开 DataContractSerializer 如此严格的原因不谈,您能否提出解决方法?也许是一篇关于如何与非常旧的数据合约保持向后兼容的好文章,在您对格式进行第 100 次重大更改时不会变得笨拙。

this article 中有一些额外的指导方针,但这一定是为了不同的目的而编写的。例如,我们不可能让旧数据成员永远闲逛(第 9 点)。似乎大多数此类文章都是从通信协议的角度编写的,而不是将数据存储在文件中。

【问题讨论】:

    标签: .net datacontractserializer


    【解决方案1】:

    1 年后,我不得不说DataContractSerializer 的版本控制真的很烂。它太僵硬了。它真的适用于不太可能改变的合同,然后只能以特定的方式改变。您必须做额外的工作才能使用它来使其快速 - 例如 KnownTypeAttribute。如果您需要相对快速的序列化,我只会推荐它 - 可以说,这对于它的设计目的相当重要。

    我从事的另一个项目使用了更灵活的序列化程序,例如,它不会跳过调用类构造函数(某些事情造成了很多不便),并且不需要项目按特定顺序排列。它优雅地处理新字段(它们保留在构造函数设置的任何位置)并在零程序员干预的情况下删除字段。

    现在要是我能把它贴在这里就好了……不过它比 DataContractSerializer 慢了大约 5 到 10 倍。

    【讨论】:

    • 首先感谢您发表这篇文章,我正要踏上与您去年一样的噩梦。我很难找到 DataContractSerializer 的良好替代品,我认为您的其他 Serializer 是专有的,因此您无法共享它?
    【解决方案2】:

    我认为您对内置版本控制支持期望过高。它的真正目的是允许您添加新成员,同时保留所有现有功能和成员。

    在对合同进行重大更改的情况下,您可能最好创建一个新版本的合同(例如,使用新的命名空间 - 常见的约定是使用后缀 yyyy/mm,例如 http://mycompany.com/myservices/2009/10) .

    然后,您需要能够支持尽可能多的旧合同,并且需要能够在每个支持的合同和您当前使用的任何内部表示之间进行转换。

    【讨论】:

    • 这是一份相当大的合同;例如,我真的不想复制和粘贴其中的大部分内容,只是为了将布尔“已启用”更改为枚举“状态”。我将坚持使用 XML 预处理,尽管问题中描述了这些问题,但它通常很容易实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 2010-10-29
    • 2012-05-17
    相关资源
    最近更新 更多