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;
    }
}
4

2 に答える 2

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;
}
于 2009-12-12T21:34:02.393 に答える
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;

}
于 2009-12-12T21:39:25.893 に答える