我正在通过API为另一个程序编写插件。为了保存它的当前状态,我的插件通过将其序列化为XML并将其存储在用户字符串(API提供的功能)中,将Project对象的实例存储到该文件中。它还存储一个单独的字符串,其中包含当前正在使用的插件的版本号。
当用户打开文件时,我的插件会检查版本号。如果当前插件版本与文件中存储的版本不同,则会弹出一条消息,警告用户该版本不同,该文件可能导致插件崩溃。
我宁愿提供一组迁移脚本,当用户在较新版本的插件中打开旧文件时,这些脚本会自动运行。我的问题是,这些通常在哪里,它们是如何组织的?
另外说我的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 :(得分: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;
}
答案 1 :(得分: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;
}