Как использовать ImmutableArray (C #) в MongoDB? - PullRequest
1 голос
/ 04 мая 2019

Я пытаюсь сохранить ImmutableArray (System.Collections.Immutable) в MongoDB.

Я пробовал MongoDB.Immutable, но он ограничен старой версией пакета Immutable и не поддерживает ImmutableArray.

Я попытался создать собственный сериализатор, используя IBsonSerializer и IBsonSerializationProvider + SerializerBase, но безуспешно.

[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();
    }
}

или

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());
    }
}

Первое решение выдает эту ошибку:

System.Runtime.Serialization.SerializationException: Тип 'System.Collections.Immutable.ImmutableArray`1 [[System.Int32, mscorlib, Версия = 4.0.0.0, Культура = нейтральный, PublicKeyToken = b77a5c561934e089]]' с именем контракта данных 'ArrayOfint: http://schemas.microsoft.com/2003/10/Serialization/Arrays' не ожидается. Рассмотрите возможность использования DataContractResolver, если вы используете DataContractSerializer или добавляете любые типы, которые не известны статически, в список известных типов - например, с помощью атрибута KnownTypeAttribute или добавляя их в список известных типов, передаваемых сериализатору.

Второй бросает:

System.ArgumentException: GenericArguments [0], 'System.Collections.Immutable.ImmutableArray 1[System.Int32]', on 'MongoDB.Bson.Serialization.Serializers.EnumerableInterfaceImplementerSerializer 2 [TValue, TItem]' нарушает ограничение типа 'TValue'. ---> System.TypeLoadException: GenericArguments [0], 'System.Collections.Immutable.ImmutableArray 1[System.Int32]', on 'MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase 2 [TValue, TItem]' нарушает ограничение параметра типа 'TValue'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...