Передача информации о типе в MongoDB, чтобы он мог правильно десериализовать типы интерфейса?

У меня есть класс, который я сериализую в MongoDB как BsonDocument, этот класс также имеет свойство типа IMyInterface.

public interface IMyInterface
{
    String Name { get; set; }
}

public class MyClass
{
    public IMyInterface IntRef { get; set; }
}

В течение MyClass времени жизни экземпляров объектов IntRef может ссылаться на несколько разных классов, реализующих IMyInterface. После сериализации я обнаружил, что все данные из класса, на который указывает IntRef, также сериализуются в BsonDocument, а не только Name.

Однако при десериализации BsonDocument.Deserialize не имеет информации о Type класса, на который указывает IntRef, и выдает исключение. Как я могу предоставить информацию Type для моего звонка Deserialize?

У меня также есть наивный обходной путь, когда я Deserialize часть документа, которая является IntRef, работает хорошо. Учитывая правильный класс Type, BsonDocument.Deserialize возвращает экземпляр объекта этого Type. Хотя проблема здесь в том, что я все еще не могу Deserialize верхнего уровня BsonDocument представлять MyClass, потому что он все еще содержит поддокумент, относящийся к IntRef. Есть ли способ заставить Deserialize игнорировать часть BsonDocument? Мне пришла в голову идея просто установить MyBsonDocument[SubDocName] = null, несмотря на то, что оно не может принимать значения NULL.


person KDecker    schedule 04.04.2016    source источник
comment
У меня самого ограниченный опыт работы с Mongo и BsonDocument, но поскольку у вас не было ответов, видели ли вы это ТАК вопрос?   -  person Crowcoder    schedule 05.04.2016
comment
Хм. Я думаю, это близко, хотя это не для того, чтобы сериализовать какую-то часть объекта, а не для того, чтобы не десериализовать его. Хотя... Я думаю, что ClassMap может быть частью ответа. Надо будет глянуть, такого я еще не видел.   -  person KDecker    schedule 05.04.2016


Ответы (1)


В результате того, что MyClass указывает на тип интерфейса, который затем может содержать любой класс Bson, реализующий этот интерфейс, мы должны сообщить MongoDB тип класса, который может быть в конце этого (всего) интерфейса. Затем он может сделать вывод из классов, что он знает, как десериализовать определенные BsonDocuments, содержащие Bson этого класса.

public interface IMyInterface
{
    String Name { get; set; }
}

public class MyIntImpl : IMyInterface
{
    public String Name { get; set; }
}

public class MyClass
{
    public IMyInterface IntRef { get; set; }

    public MyClass()
    {
        IntRef = new MyIntImpl();
    }
}

// When starting up MongoDB
private void RegisterClasses()
{
    BsonClassMap.RegisterClassMap<MyIntImpl>();
}

Добавив класс MyIntImpl в BsonClassMap, теперь он знает, как десериализовать Bson из этого типа класса. Вам просто нужно убедиться, что карта заполнена классами, которые реализуют интерфейсы, которые вы можете сериализовать.

Некоторые справочные ссылки: Обзор от высокого до низкого уровня сериализации C# MongoDB, сообщение SO с описанием решения.

person KDecker    schedule 05.04.2016