在MessagePack中使用接口作为属性类型序列化对象

时间:2013-09-29 17:21:13

标签: c# serialization messagepack

我正在尝试序列化作为接口的属性的对象,MessagePack抛出“SerializationException”,表示该接口没有序列化。

代码示例:

namespace ConsoleApplication1
{
  // interfaces and classes declaration

  public interface IDummyInterface { }

  public class DummyObject : IDummyInterface
  {
    public string Value { get; set; }
  }

  public class SmartObject
  {
    public string Name { get; set; }

    IDummyInterface DummyOne { get; set; }
  }

  // in main
  var mySmartObject = new SmartObject() { Name = "Yosy", DummyOne = new DummyObject() { Value = "Value"} };

  using(var stream = new MemoryStream())
  {
    var serializer = MessagePackSerializer.Create<SmartObject>();
    serializer.Pack(mySmartObject, stream); // => This code throws the exception
  }
}

我可以告诉messagepack使用哪个序列化程序用于IDummyInterface并告诉他充当DummyObject吗?

1 个答案:

答案 0 :(得分:1)

在我看来您正在使用msgpack-cli。要使其正常工作,基本上有两种方法可以实现。

1。使用MessagePackKnownTypeAttribute

这个简单而直接。

public class SmartObject
{
    public string Name { get; set; }

    [MessagePackKnownType("d", typeof(DummyObject))]
    public IDummyInterface DummyOne { get; set; } // Need to make this property public
}

2。实施自定义序列化器

如果您想要一个干净的模型类而不引用MsgPack库,则可以执行以下操作,但是您需要找出一种序列化/反序列化 SmartObject的方法。 (有效)。

public class SmartObjectSerializer : MessagePackSerializer<SmartObject>
{
    public SmartObjectSerializer(SerializationContext ownerContext) : base(ownerContext)
    {
    }

    protected override void PackToCore(Packer packer, SmartObject objectTree)
    {
        var str = ToString(objectTree); // TODO: Just an example
        packer.Pack(str);
    }

    protected override SmartObject UnpackFromCore(Unpacker unpacker)
    {
        var str = unpacker.LastReadData.AsStringUtf8(); // TODO: Just an example
        return new SmartObject
        {
            // TODO: Initialize based on str value
        };
    }
}

// In main
var context = new SerializationContext();
context.Serializers.RegisterOverride(new SmartObjectSerializer(context));

var serializer = MessagePackSerializer.Get<SmartObject>(context);
// The rest is the same

您可能有兴趣看一些示例代码。