I am trying to save ImmutableArray (System.Collections.Immutable) in MongoDB.

I tried MongoDB.Immutable but it is limited to old version of Immutable package, and doesn't support ImmutableArray.

I tried to create a custom serializer either using IBsonSerializer and IBsonSerializationProvider + SerializerBase without success.

[BsonSerializer(typeof(BsonImmutableSerializer<>))]
public class BsonImmutableSerializer<T> : IBsonSerializer<ImmutableArray<T>>
{
    public Type ValueType => typeof(ImmutableArray<T>);

    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return context.Reader.ReadString().FromJson<ImmutableArray<T>>().ToImmutableArray();
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
    {
        context.Writer.WriteString(value.ToJson());
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, ImmutableArray<T> value)
    {
        context.Writer.WriteString(value.ToJson());
    }

    ImmutableArray<T> IBsonSerializer<ImmutableArray<T>>.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return context.Reader.ReadString().FromJson<ImmutableArray<T>>().ToImmutableArray();
    }
}

or

public class ImmutableProvider<T> : IBsonSerializationProvider
{
    public IBsonSerializer GetSerializer(Type type)
    {
        return type == typeof(ImmutableList<T>) ? new ImmutableSerializer<T>() : null;
    }
}

public class ImmutableSerializer<T> : SerializerBase<ImmutableList<T>>
{
    public override ImmutableList<T> Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return context.Reader.ReadString().FromJson<List<T>>().ToImmutableList();
    }

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, ImmutableList<T> value)
    {
        context.Writer.WriteString(value.ToJson());
    }
}

The first solution throws this error:

System.Runtime.Serialization.SerializationException: Type 'System.Collections.Immutable.ImmutableArray`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' with data contract name 'ArrayOfint:http://schemas.microsoft.com/2003/10/Serialization/Arrays' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.

The second one throws:

System.ArgumentException: GenericArguments[0], 'System.Collections.Immutable.ImmutableArray1[System.Int32]', on 'MongoDB.Bson.Serialization.Serializers.EnumerableInterfaceImplementerSerializer2[TValue,TItem]' violates the constraint of type 'TValue'. ---> System.TypeLoadException: GenericArguments[0], 'System.Collections.Immutable.ImmutableArray1[System.Int32]', on 'MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase2[TValue,TItem]' violates the constraint of type parameter 'TValue'.

0 Answers