(反)序列化特定子类而不使用 [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