Skip to content

Cant serialize custom type derived from IDictionary<,> #1686

@MrReny

Description

@MrReny

Bug description

I Have a type derived from IDictionary<,> it incapsulates field of same type and has only one constructor that asccepets IDictionary<,> as only parameter

[MessagePackObject]
public class DeviceCommands : IDictionary<CommandId, CommandDescriptor>, IEquatable<DeviceCommands>
{
    [IgnoreMember]
    public static readonly DeviceCommands Empty = new (new Dictionary<CommandId, CommandDescriptor>());

    [Key(0)] public IDictionary<CommandId, CommandDescriptor> Commands { get; }

    [SerializationConstructor]
    public DeviceCommands(IDictionary<CommandId, CommandDescriptor> commands)
    {
        Commands = commands;
    }

    //... IDictionary<CommandId, CommandDescriptor> impl stuff


    //... IEquatable<DeviceCommands> impl stuff
}

Im running simple serialization test

private static T SerializeDeserialize<T>(T obj) =>
        MessagePackSerializer.Deserialize<T>(MessagePackSerializer.Serialize(obj));

and have next error popup

MessagePack.MessagePackSerializationException : Failed to serialize ArmKip.Interfaces.Device.DeviceCommands value.
  ----> System.TypeInitializationException : The type initializer for 'FormatterCache`1' threw an exception.
  ----> System.ArgumentException : GenericArguments[2], 'ArmKip.Interfaces.Device.DeviceCommands', on 'MessagePack.Formatters.GenericDictionaryFormatter`3[TKey,TValue,TDictionary]' violates the constraint of type 'TDictionary'.
  ----> System.TypeLoadException : GenericArguments[2], 'ArmKip.Interfaces.Device.DeviceCommands', on 'MessagePack.Formatters.GenericDictionaryFormatter`3[TKey,TValue,TDictionary]' violates the constraint of type parameter 'TDictionary'.
   at MessagePack.MessagePackSerializer.Serialize[T](MessagePackWriter& writer, T value, MessagePackSerializerOptions options)
   at MessagePack.MessagePackSerializer.Serialize[T](T value, MessagePackSerializerOptions options, CancellationToken cancellationToken)
   at ArmKip.Interfaces.Tests.SerializationsTests.SerializeDeserialize[T](T obj) in C:\Programming\armkip\ArmKip.Tests\ArmKip.Interfaces.Tests\SerializationTests.cs:line 434
   at ArmKip.Interfaces.Tests.SerializationsTests.DeviceCommands_SerializationTest() in C:\Programming\armkip\ArmKip.Tests\ArmKip.Interfaces.Tests\SerializationTests.cs:line 189
--TypeInitializationException
   at MessagePack.Resolvers.DynamicGenericResolver.GetFormatter[T]()
   at MessagePack.Resolvers.StandardResolver.FormatterCache`1..cctor()
--- End of stack trace from previous location ---
   at MessagePack.FormatterResolverExtensions.Throw(TypeInitializationException ex)
   at MessagePack.MessagePackSerializer.Serialize[T](MessagePackWriter& writer, T value, MessagePackSerializerOptions options)
--ArgumentException
   at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
   at System.RuntimeType.MakeGenericType(Type[] instantiation)
   at MessagePack.Internal.DynamicGenericResolverGetFormatterHelper.GetFormatter(Type t)
   at MessagePack.Resolvers.DynamicGenericResolver.FormatterCache`1..cctor()
--TypeLoadException
   at System.RuntimeTypeHandle.Instantiate(QCallTypeHandle handle, IntPtr* pInst, Int32 numGenericArgs, ObjectHandleOnStack type)
   at System.RuntimeTypeHandle.Instantiate(Type[] inst)
   at System.RuntimeType.MakeGenericType(Type[] instantiation)

On other hand i have several classes that buildt very similar.
The only diffirenence is that they implement and use IReadOnlyDictionary<,> instead
They serialize and deserialize just fine

I actualy tested adding more properties to class and arguments to constructor. Does not help.

Expected behavior

I expect serialization work without error just like with classes implementing IReadOnlyDictionary<,>

My run env

  • Version used: 2.5.129
  • Runtime: .NET 6

More context

Im noticed that IReadOnlyDictionary<,> had some treatment in #1187, assume hence a difference in behaviour

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions