msgpack-cli icon indicating copy to clipboard operation
msgpack-cli copied to clipboard

ResolveSerializerEventArgs.SetSerializer doesn't allow to set a serializer of a base type.

Open aidin36 opened this issue 7 years ago • 4 comments

Assume the following classes. I handled SerializationContext.ResolveSerializer event, and handler will get called when serializer tries to serialize ChildData. Though DataSerializer can serialize ChildData class, the ResolveSerializerEventArgs.SetSerializer doesn't let me set DataSerializer as the serializer. I have to set a class that explicitly implemented MessagePackSerializer<ChildData>.

This shouldn't be like this, because if I get the serializer with Context.GetSerializer<IData>();, it can handle the ChildData instance correctly. So SetSerializer method should allow me to set that as the ChildData's serializer.

    public class IData
    {
    }

    public class BaseData : IData
    {
        public int DataField { get; set; }
    }

    public class ChildData : BaseData
    {
    }

    public class DataSerializer : MessagePackSerializer<IData>
    {
        public DataSerializer(SerializationContext ownerContext)
            : base(ownerContext)
        {
        }

        protected override void PackToCore(MsgPack.Packer packer, IData objectTree)
        {
            ...
        }

        protected override IData UnpackFromCore(MsgPack.Unpacker unpacker)
        {
            ...
        }
    }

aidin36 avatar Nov 19 '16 13:11 aidin36

Thank you for reporting! I'm checking just to be sure、but do you mean that you get InvalidOperationException when you set to DataSerializer? If so, it is design bug...

yfakariya avatar Nov 20 '16 05:11 yfakariya

Yes, exactly.

I receive:

InvalidOperationException: The serializer must be MsgPack.Serialization.MessagePackSerializer`1[MsgPackTest.ChildData] type.

Here's a sample implementation of ResolveSerailizer:

static void context_ResolveSerializer(object sender, ResolveSerializerEventArgs e)
{
    if (typeof(IData).IsAssignableFrom(e.TargetType))
    {
        e.SetSerializer<IData>(new BaseDataSerializer(e.Context));
    }
}

aidin36 avatar Nov 22 '16 11:11 aidin36

Sorry for delay. I see, I will fix this.

yfakariya avatar Nov 29 '16 14:11 yfakariya

Sorry I forgot about restrictions about generic arguments variance of .NET. I'm thinking solution for it, but it takes more time to fix or it cannot be fixed

yfakariya avatar Dec 04 '16 10:12 yfakariya