(反)序列化特定子类而不使用 [ProtoInclude]
(De)serializing specific subclass without using [ProtoInclude]
我正在考虑将当前基于 WCF 的应用程序迁移到 protobuf-net.Grpc。这似乎是可行的,但是我无法使 (DTO classes) base class 的 protobuf-net 序列化属性不包含所有派生的 classes 和 [ProtoInclude] 属性。
简化的 class 层次结构:
[DataContract]
public abstract class DtoBase
{
[DataMember(Order = 1)]
public int Id { get;set; }
[DataMember(Order = 2)]
public int Version { get;set; }
[DataMember(Order = 3)]
public EditState EditState { get;set; }
}
[DataContract]
public class PersonDto : DtoBase
{
[DataMember(Order=4)]
public string FirstName { get;set; }
[DataMember(Order=5)]
public string LastName { get;set; }
}
我调查了相关问题,归结为在反序列化过程中应该知道特定类型的事实——或者应该有一种方法来确定它。我们的服务方法已经知道要使用的特定 subclass,例如我们有像
这样的方法
[ServiceContract]
public interface IPersonService
{
[OperationContract]
ScalarResult<PersonDto> GetById(personId);
}
DataContractSerializer 可以做到这一点——反序列化基础 class 属性,当特定的 subclass 已知时。当您反序列化具有基本 class 签名的 subclass 时,它需要提示(已知类型),例如返回 PersonDto 而不是 DtoBase。但是当特定的 subclass 已知时,不需要已知的类型,一切正常。
所以问题是如何对 protobuf-net 做同样的事情?如果不可能,为什么?
Protobuf-net 与任何库一样,会做出某些假设和妥协。如果它想支持额外的场景,它们需要被指定、设计、实施、测试和支持——所有这些都需要时间。到目前为止,您描述的场景:还没有投入那个时间。
可能可以使用RuntimeTypeModel
API配置基本类型属性,但我必须强调:每当出现问题时,本质上是:
My existing model isn't working well with my chosen serializer
我的默认回答(基于该领域几十年的经验)是:
If your existing model isn't a great fit for a different serializer: stop fighting the serializer. Instead, create a new model that works perfectly with your new choice of serializer, and shim between models at the point of (de)serialization
我正在考虑将当前基于 WCF 的应用程序迁移到 protobuf-net.Grpc。这似乎是可行的,但是我无法使 (DTO classes) base class 的 protobuf-net 序列化属性不包含所有派生的 classes 和 [ProtoInclude] 属性。
简化的 class 层次结构:
[DataContract]
public abstract class DtoBase
{
[DataMember(Order = 1)]
public int Id { get;set; }
[DataMember(Order = 2)]
public int Version { get;set; }
[DataMember(Order = 3)]
public EditState EditState { get;set; }
}
[DataContract]
public class PersonDto : DtoBase
{
[DataMember(Order=4)]
public string FirstName { get;set; }
[DataMember(Order=5)]
public string LastName { get;set; }
}
我调查了相关问题,归结为在反序列化过程中应该知道特定类型的事实——或者应该有一种方法来确定它。我们的服务方法已经知道要使用的特定 subclass,例如我们有像
这样的方法[ServiceContract]
public interface IPersonService
{
[OperationContract]
ScalarResult<PersonDto> GetById(personId);
}
DataContractSerializer 可以做到这一点——反序列化基础 class 属性,当特定的 subclass 已知时。当您反序列化具有基本 class 签名的 subclass 时,它需要提示(已知类型),例如返回 PersonDto 而不是 DtoBase。但是当特定的 subclass 已知时,不需要已知的类型,一切正常。
所以问题是如何对 protobuf-net 做同样的事情?如果不可能,为什么?
Protobuf-net 与任何库一样,会做出某些假设和妥协。如果它想支持额外的场景,它们需要被指定、设计、实施、测试和支持——所有这些都需要时间。到目前为止,您描述的场景:还没有投入那个时间。
可能可以使用RuntimeTypeModel
API配置基本类型属性,但我必须强调:每当出现问题时,本质上是:
My existing model isn't working well with my chosen serializer
我的默认回答(基于该领域几十年的经验)是:
If your existing model isn't a great fit for a different serializer: stop fighting the serializer. Instead, create a new model that works perfectly with your new choice of serializer, and shim between models at the point of (de)serialization