2009-12-12 55 views
1

我正在通過API爲另一個程序編寫一個插件。爲了保存它的當前狀態,我的插件將一個Project對象的實例存儲到文件中,將其序列化爲XML並將其存儲在用戶字符串中,這是API提供的一項功能。它還存儲一個單獨的字符串,其中包含當前正在使用的插件的版本號。組織文件版本遷移代碼的最佳方式是什麼?

當用戶打開文件時,我的插件會檢查版本號。如果當前插件版本與存儲在該文件中的版本不同,則會彈出一條警告用戶提供不同版本的消息,並指出該文件可能導致插件崩潰。

我寧願提供一組遷移腳本,當用戶在較新版本的插件中打開較舊的文件時,這些腳本會自動運行。我的問題是,這些通常在哪裏,他們是如何組織的?

也說我的項目類之間的變化顯着版本之間嘗試從舊文件反序列化項目將失敗與新的Project類。我不想保留每個版本的Project類的副本都是我的程序集,但同時不得不通過XML解析會更加痛苦。假設解析XML是最好的選擇,任何人都可以提出一個更有組織的方式來做到這一點,然後下面的代碼?

public string MigrateProject(int fileVersion, int plugInversion, string proj) 
{ 
    if(fileVersion>plugInversion) 
    { 
     //tell user to upgrade their copy of the plugin 
     return null; 
    } 

    if(fileVersion ==1) 
    { 
     string v2 = Migrate1to2(serializedProject); 
     string v3 = Migrate2to3(v2); 
     string v4 = Migrate3to4(v3); 
     return v4; 
    } 
    else if(fileVersion ==2) 
    { 
     string v3 = Migrate2to3(serializedProject); 
     string v4 = Migrate3to4(v3); 
     return v4; 
    } 
    else if(fileVersion ==3) 
    { 
     string v4 = Migrate3to4(serializedProject); 
     return v4; 
    } 
    else 
    { 
     //could not migrate project message 
     return null; 
    } 
} 

回答

0

Store中的遷移方法列表如下:

List<Func<string,string>> myMigrateMethods = new List<Func<string,string>>(); 
myMigrateMethods.Add(Migrate1To2); 
myMigrateMethods.Add(Migrate2To3); 
myMigrateMethods.Add(Migrate3To4); 

然後遍歷列表從適當的方法開始:

public string MigrateProject(int fileVersion, int plugInversion, string proj) 
{ 
    if(fileVersion>plugInversion) 
    { 
     //tell user to upgrade their copy of the plugin 
     return null; 
    } 

    //user already at max version 
    if(fileVersion >= (myMigrateMethods.Length-1)) return null; 

    var firstMigrateMethodNeeded = (fileVersion-1); //array is 0-based 

    var output = serializedProject; 
    for(var i= firstMigrateMethodNeeded; i< myMigrateMethods.Length; i++) 
    { 
     output = myMigrateMethods[i](output); 
    } 

    return output; 

} 
1

XmlSerializer不具有版本容錯性,沒有包含可以手動執行反序列化操作的版本字段。

BinaryFormatter支持與SoapFormatter和DataContractSerializer一樣的版本。

你仍然需要處理的轉化,可以很容易地削減這樣的代碼:

if(fileVersion ==1) 
{ 
    serializedProject = Migrate1to2(serializedProject); 
    fileVersion = 2; 
} 
if(fileVersion ==2) 
{ 
    serializedProject = Migrate2to3(serializedProject); 
    fileVersion = 3; 
} 
if(fileVersion ==3) 
{ 
    serializedProject = Migrate3to4(serializedProject); 
    fileVersion = 4 
} 
else 
{ 
    //could not migrate project message 
    return null; 
} 
相關問題