2009-10-03 86 views
6

閱讀Data Contract Versioning後,我們得出結論:這並不是真正的全部內容。例如,如果您曾經擁有ValueA,會發生什麼情況,並且在新版本中它現在稱爲ValueB並且是不同類型的,您需要將ValueA轉換爲ValueB?使用DataContractSerializer進行版本控制的簡單數據文件

我可以使用一些callbacks來幫助解決這個問題,但如果我們預計格式會在很長一段時間內頻繁更改,它看起來不是一個非常可維護的解決方案。

我們爲入駐的解決辦法是保持一個「的版本保存的」現場,並在加載文件調用特定舊版本的轉換程序的要求。這些轉換例程知道如何將舊數據的XML轉換爲新數據的XML。

但是,事實證明,DataContractSerializes requires the order of the elements to be exactly what it expects。這意味着我們的轉換過程必須知道將元素插入到正好是的正確位置。如果考慮繼承,這比簡單地添加一個已知名稱的元素要困難得多。有了繼承,你不能可靠地或AddAfterSelf任何場,僅僅是因爲沒有一個單一的領域,始終是旁邊這個新領域。

撇開DataContractSerializer做得如此嚴格的原因,你能否提出解決方法?也許是一篇關於如何保持與舊數據合同向後兼容的偉大文章,在您對格式進行第100次重大更改時不會變得笨拙。

有在this article一些額外的指導方針,但必須用於不同的目的已經被寫入。例如,我們不可能讓舊數據成員永遠懸掛(第9點)。看來,大多數這樣的文章是從通信協議的角度來編寫的,而不是將數據存儲在文件中。

回答

2

我認爲你對內置的版本支持期望過高。它的目的是允許您添加新成員,同時保留所有現有功能以及成員。

在重大更改,以合同的情況下,你可能會得到更好的創建合同的新版本(例如使用新的命名空間 - 一個共同的約定使用後綴爲yyyy/mm,例如http://mycompany.com/myservices/2009/10)。

然後,您需要能夠支持儘可能多的老合同,只要適合,並且需要能夠支持每一個合同,無論當前內部表示你正在使用之間的轉換。

+0

這是一個非常大的合同;我真的很討厭複製和粘貼大部分內容,只是爲了將bool「Enabled」更改爲枚舉「狀態」。我將堅持使用XML預處理,儘管存在問題中描述的問題,但它實際上很容易實現。 – 2009-10-04 10:28:45

4

1年後我不得不說,DataContractSerializer真的吸吮版本。它太僵硬了。這確實意味着不太可能改變的合同,然後只用特定的方式。您必須做額外的工作才能使其更快 - 例如KnownTypeAttribute。如果你需要相對較快的序列化,我只會推薦它 - 可以說,它對於它的設計非常重要。

我工作的另一個項目使用了一個更靈活的序列化程序,例如,它不會跳過調用類構造函數(有些事情已經造成了很多不便),並且不需要按特定順序排列項目。它優雅地處理新字段(它們留在構造函數設置的任何位置),並且在零程序員干預的情況下刪除字段。

現在,如果我能在這裏發佈...但是它是約5倍,10倍比DataContractSerializer的慢。

+0

首先感謝您發表這篇文章,我即將展開與去年一樣的噩夢。我無法找到DataContractSerializer的一個很好的替代方案,我認爲您的其他Serializer是專有的,因此您無法共享它? – Jambobond 2010-10-22 11:54:37

+0

@Jambobond恐怕是這樣:( – 2010-10-22 16:44:46