2009-12-12 3 views
1

Я пишу плагин для другой программы через API. Чтобы сохранить текущее состояние, мой плагин хранит экземпляр объекта Project в файле, сериализуя его в XML и сохраняя в пользовательской строке, предоставляемой API. Он также хранит отдельную строку, содержащую номер версии подключаемого модуля, который в настоящее время используется.Каков наилучший способ организовать код миграции версии файла?

Когда пользователь открывает файл, мой плагин проверяет номера версий. Если текущая версия плагина не совпадает с версией, хранящейся в файле, она выведет сообщение, предупреждающее пользователя о другой версии и что файл может привести к сбою подключаемого модуля.

Я бы скорее предоставил набор сценариев миграции, которые запускаются автоматически, когда пользователь открывает более старый файл в более новой версии подключаемого модуля. Мой вопрос, хотя, где они обычно идут и как они организованы?

Также скажите, что мой класс Project значительно меняется между версиями, где попытка десериализации проекта из старого файла завершится неудачей с новым классом 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

Храните ваши методы мигрировать в список, как это:

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; 
} 
Смежные вопросы