다음을 통해 공유


이전 버전과의 호환성 지침

이전 버전과 호환되는 코드를 작성하는 것은 어려울 수 있으며 테스트하기도 힘듭니다. 이 문서에서는 .NET Orleans에서 이전 버전과 호환되는 코드를 작성하기 위한 지침을 설명합니다. 이 문서에서는 VersionAttributeObsoleteAttribute의 사용법을 다룹니다.

기존 메서드의 서명을 변경하지 않음

Orleans 직렬 변환기가 작동하는 방식 때문에 기존 메서드의 서명을 변경해서는 안 됩니다.

다음 예제는 정확합니다.

[Version(1)]
public interface IMyGrain : IGrainWithIntegerKey
{
    // First method
    Task MyMethod(int arg);
}
[Version(2)]
public interface IMyGrain : IGrainWithIntegerKey
{
    // Method inherited from V1
    Task MyMethod(int arg);

    // New method added in V2
    Task MyNewMethod(int arg, obj o);
}

다음은 잘못되었습니다.

[Version(1)]
public interface IMyGrain : IGrainWithIntegerKey
{
    // First method
    Task MyMethod(int arg);
}
[Version(2)]
public interface IMyGrain : IGrainWithIntegerKey
{
    // Method inherited from V1
    Task MyMethod(int arg, obj o);
}

Important

코드에서 이 변경을 수행하면 안 됩니다. 이는 매우 좋지 않은 부작용을 초래하는 나쁜 습관의 한 예이기 때문입니다. 매개 변수 이름을 바꾸는 경우 발생할 수 있는 일의 예입니다. 클러스터에 다음 두 인터페이스 버전이 배포되어 있다고 가정해 보겠습니다.

[Version(1)]
public interface IMyGrain : IGrainWithIntegerKey
{
    // return a - b
    Task<int> Subtract(int a, int b);
}
[Version(2)]
public interface IMyGrain : IGrainWithIntegerKey
{
    // return a - b
    Task<int> Subtract(int b, int a);
}

이 메서드는 동일하게 보입니다. 그러나 클라이언트가 V1을 사용하여 호출되면 요청이 V2 활성화에 의해 처리됩니다.

var grain = client.GetGrain<IMyGrain>(0);
var result = await grain.Subtract(5, 4); // Will return "-1" instead of expected "1"

이는 내부 Orleans 직렬 변환기가 작동하는 방식 때문입니다.

기존 메서드 논리 변경 방지

당연해 보이지만 기존 메서드의 본문을 변경할 때는 매우 주의해야 합니다. 버그를 수정하지 않는 한, 코드를 수정해야 하는 경우 새 메서드를 추가하는 것이 좋습니다.

예시:

// V1
public interface MyGrain : IMyGrain
{
    // First method
    Task MyMethod(int arg)
    {
        SomeSubRoutine(arg);
    }
}
// V2
public interface MyGrain : IMyGrain
{
    // Method inherited from V1
    // Do not change the body
    Task MyMethod(int arg)
    {
        SomeSubRoutine(arg);
    }

    // New method added in V2
    Task MyNewMethod(int arg)
    {
        SomeSubRoutine(arg);
        NewRoutineAdded(arg);
    }
}

조직 인터페이스에서 메서드를 제거하지 마세요.

더 이상 사용되지 않는 경우가 아니라면 조직 인터페이스에서 메서드를 제거하면 안 됩니다. 메서드를 제거하려면 다음 두 단계로 수행해야 합니다.

  1. V1 메서드가 Obsolete로 표시된 V2 조직 배포

    [Version(1)]
    public interface IMyGrain : IGrainWithIntegerKey
    {
        // First method
        Task MyMethod(int arg);
    }
    
    [Version(2)]
    public interface IMyGrain : IGrainWithIntegerKey
    {
        // Method inherited from V1
        [Obsolete]
        Task MyMethod(int arg);
    
        // New method added in V2
        Task MyNewMethod(int arg, obj o);
    }
    
  2. V1 호출이 없는 것이 확실하면(실제로 V1이 실행 중인 클러스터에 더 이상 배포되지 않음) V1 메서드가 제거된 V3을 배포합니다.

    [Version(3)]
    public interface IMyGrain : IGrainWithIntegerKey
    {
        // New method added in V2
        Task MyNewMethod(int arg, obj o);
    }