다음을 통해 공유


protobuf-net(이진)으로 마이그레이션합니다.

protobuf-net 라이브러리는 .NET용 계약 기반 직렬 변환기로, 이진 프로토콜 버퍼serialization 형식을 사용합니다. API는 일반적인 .NET 패턴을 따르며 XmlSerializerDataContractSerializer와(과) 대체로 유사합니다.

protobuf-net의 일부 동작 및 기능은 마이그레이션 중에 주목할 만한 것이며, 많은 시나리오에서는 BinaryFormatter멤버에 특성을 적용해야 합니다.

  • 기본적으로 public 형식과 public이 아닌 형식은 모두 직렬화할 수 있으며 serializer에는 매개 변수가 없는 생성자가 예상됩니다.
  • protobuf-net에는 특성으로 [ProtoContract] 주석을 달 수 있는 각 직렬화 가능한 형식이 필요합니다. 이 특성은 필요에 따라 SkipConstructor = true 속성을 지정 하여 특정 생성자의 필요성을 제거할 수 있습니다.
  • 직렬화할 수 있는 모든 비정적 필드와 속성은 특성으로 [ProtoMember(int identifier)] 주석을 추가해야 합니다. 멤버 이름은 데이터에 인코딩되지 않습니다. 대신, 사용자는 해당 형식 내에서 고유해야 하는 각 멤버를 식별하기 위해 양의 정수를 선택해야 합니다.
  • 상속 은 알려진 하위 형식이 있는 각 형식의 특성을 통해 [ProtoInclude(...)] 명시적으로 선언되어야 합니다.
  • 읽기 전용 필드는 기본적으로 지원됩니다.
  • 또는 특성이 없는 일부 튜플과 유사한 형식은 생성자 패턴에서 인식됩니다. 선언된 모든 공용 멤버와 일치하는 매개 변수가 있는 생성자가 있는 형식은 튜플로 해석되고 매개 변수 순서는 해당 멤버의 식별자를 유추하는 데 사용됩니다.
  • protobuf-net.BuildTools 디자인 타임 패키지를 사용하는 것이 좋습니다. 일반적인 오류에 대한 컴파일 시간 경고를 제공합니다.

단계별 마이그레이션

  1. BinaryFormatter의 모든 사용 현황을 찾습니다.
  2. 코드 경로가 serialization 테스트로 덮여 있는지 확인하여 변경 내용을 확인하고 버그가 발생하지 않도록 할 수 있습니다.
  3. 패키지를 설치 protobuf-net 합니다(선택 사항 protobuf-net.BuildTools).
  4. BinaryFormatter을 사용하여 직렬화되는 모든 형식을 찾습니다.
  5. 수정할 수 있는 형식의 경우:
    • 인터페이스로 [ProtoContract] 표시되거나 구현되는 모든 형식의 특성에 [Serializable] 주석을 ISerializable 추가합니다. 이러한 형식이 다른 직렬 변환기를 DataContractSerializer사용할 수 있는 다른 앱(예: 라이브러리 작성 중)에 노출되지 않는 경우 주석 및 [Serializable] 주석을 ISerializable 제거할 수 있습니다.
    • 파생 형식의 경우 기본 형식에 적용 [ProtoInclude(...)] 합니다(아래 예제 참조).
    • 매개 변수를 허용하는 모든 생성자를 선언하는 모든 형식에 대해 매개 변수가 없는 생성자를 추가하거나 특성에 SkipConstructor = true 지정 [ProtoContract] 합니다. protobuf-net 요구 사항을 설명하는 주석을 남겨 둡니다(실수로 제거되는 사람은 아무도 없습니다).
    • 직렬화할 모든 멤버(필드 및 속성)를 표시합니다 [ProtoMember(int identifier)]. 모든 식별자는 단일 형식 내에서 고유해야 하지만 상속을 사용하는 경우 하위 형식에서 동일한 숫자를 다시 사용할 수 있습니다.
  6. 수정할 수 없는 형식의 경우:
    • .NET 자체에서 제공하는 형식의 경우 API를 사용하여 ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type) protobuf-net에서 기본적으로 지원되는지 확인할 수 있습니다.
    • 전용 DTO(데이터 전송 개체)를 만들고 그에 따라 매핑할 수 있습니다(이에 대해 암시적 캐스트 연산자 사용 가능).
    • API를 RuntimeTypeModel 사용하여 특성이 허용하는 모든 것을 정의합니다.
  7. BinaryFormatter 의 사용량을 ProtoBuf.Serializer(으)로 교체합니다.
-[Serializable]
+[ProtoContract]
+[ProtoInclude(2, typeof(Point2D))]
public class Point1D
{
+   [ProtoMember(1)]
    public int X { get; set; }
}

-[Serializable]
+[ProtoContract]
public class Point2D : Point1D
{
+   [ProtoMember(2)]
    public int Y { get; set; }
}