2009-12-12 5 views
1

API를 통해 다른 프로그램의 플러그인을 작성하고 있습니다. 현재 상태를 저장하기 위해 내 플러그인은 XML로 직렬화하고 API에서 제공하는 기능인 사용자 문자열에 저장하여 Project 객체의 인스턴스를 파일에 저장합니다. 또한 현재 사용중인 플러그인의 버전 번호가 들어있는 별도의 문자열을 저장합니다.파일 버전 이전 코드를 구성하는 가장 좋은 방법은 무엇입니까?

사용자가 파일을 열면 플러그인이 버전 번호를 확인합니다. 현재 플러그인 버전이 파일에 저장된 버전과 같지 않은 경우 사용자에게 다른 버전에 대해 경고하는 메시지가 나타나고 파일로 인해 플러그인이 충돌 할 수 있습니다.

필자는 사용자가 새로운 버전의 플러그인에서 이전 파일을 열 때 자동으로 실행되는 마이그레이션 스크립트 세트를 제공하는 것이 좋습니다. 내 질문에 비록 이들이 보통 어디로 가고 어떻게 구성되어 있는가?

또한 내 프로젝트 클래스가 이전 파일에서 프로젝트를 deserialize하려는 경우 새 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는 사용자가 수동으로 deserialization을 수행 할 수있는 버전 필드를 포함하지 않으면 버전 관용이 아닙니다.

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; 
} 
관련 문제