我有一个工作应用程序将文档(IDocument类型)序列化到磁盘。从那里开始有另一个我可以打开该文档的应用程序(IDocument实现IPrintDocument)供查看。
我们假设我已经将一个IDocument写入磁盘,然后一周后,一个字段被添加到IDocument对象中。编写文件的程序和打开它们的程序都使用IDocument的这个新“版本”进行更新。在尝试打开之前的IDocument版本时,它会破坏(我假设 - 没有机会检查,我在这里展望)。是否有一种已知的模式可以缓解这种问题?
答案 0 :(得分:4)
是 - 使用tolerant to versioning的序列化机制。
可以预见,我将建议使用Google's Protocol Buffers,其中至少有two viable .NET实现。只要你小心,协议缓冲区都是向后兼容的 - 你可以用旧代码读取新消息,反之亦然,旧代码仍然可以保留它不理解的信息。
另一种选择是XML,无论是否使用.NET的内置XML序列化。据我所知,内置序列化在版本控制方面并不是特别灵活。
答案 1 :(得分:3)
.net内置序列化是一个选项,但它确实要求您在将来要扩展的特定部分上添加占位符。
您可以为额外的元素/属性添加占位符,如下面的代码:
[XmlAnyElement()]
public XmlElement[] ExtendedElements { get; set; }
[XmlAnyAttribute()]
public XmlAttribute[] ExtendedAttributes { get; set; }
通过在所涉及的类中添加上述内容,您可以有效地读取已保存的具有额外元素/属性的信息,修改软件知道如何处理和保存的常规属性。这允许向后和向前兼容。添加新字段时,只需添加所需的属性。
请注意,上述内容仅限于在指定的钩子中扩展。
更新:正如Jon在评论中提到的,上面只适用于xml序列化。据我所知,二进制序列化不支持类似的东西。在二进制序列化中,您可以获得应用程序的旧版/新版本以便能够读取彼此的序列化信息(.net 2.0+),但是如果将其保存回来,则会丢失版本无法处理的额外信息。
从.net 2.0开始,反序列化过程忽略了额外的数据,如果将其与可选字段组合,则可以有效地使两个应用程序读取其他版本的格式。问题是数据不像xml字段那样由类保存。
一些相关链接:http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationbinder.aspx,http://msdn.microsoft.com/en-us/library/ms229752.aspx
如果你不想要xml序列化,我会选择Jon的方法。
聚苯乙烯。我不知道是否有一些好的第三方实现,我们可以访问,扩展二进制序列化来保存和保存额外的数据。
答案 2 :(得分:1)
内置序列化应该使用[OptionalField]属性为版本更新提供最小容差。但事情可以get tricky really fast,所以你最好看看使用解决这些问题的框架,如Jons protobuffers等......
另外两个选项是为文档存储使用Sqlite之类的嵌入式数据库。并手动(或使用ORM)将对象中的属性/字段映射到表中的列。
或
使用Lucene也可以通过文档全文搜索。