2010-12-27 1 views
1

Хорошо, я задал несколько вопросов, прежде чем на SO о сериализации, но я все еще застрял - так что я думаю, что я просто выплюнул весь свой случай, а не субабъекты в надежде, что кто-то может указать мой нос в правое направление :)Сериализация графика с двунаправленными ссылками, (dll) импортными типами и версиями ..?

Мое приложение похоже на «Quartz Composer» от Apple, что означает, что у меня есть древовидная структура подключенных узлов.

Узлы определяются интерфейсом INode; фактические типы узлов/классы импортируются из DLL с использованием MEF, поэтому типы узлов не будут известны во время компиляции.

Узлы подключены, поэтому могут быть и двунаправленные связи.

Я хотел бы сохранить свою «композицию» - все дерево узлов - в файл, желательно для человека, как XML. Я действительно хочу избежать сохранения в проприетарном формате!

Так что мне нужно сериализовать это:

  • дерева объектов, чьи классы может быть импортировано во время выполнения (и, таким образом, не известно заранее), которые могут содержать двунаправленную связь.

  • Кроме того, я хотел бы сохранить информацию о версии для используемых классов узлов, поэтому можно определить, была ли сохранена «композиция» с использованием более старой версии некоторого класса узлов, чем используемый класс dll/node в текущем приложении.

Ранее я указывал на DataContractSerializer, который, кажется, как отличный инструмент для хранения моего дерева и полностью поддерживает двунаправленные связи.

Но если я хочу, чтобы сериализовать мое дерево (интерфейс IComposition), он начинает жаловаться на неизвестных типах - я должен указать каждый конкретный тип он может столкнуться при сериализации дерева ...

А также нет никакого способа, для меня указать, какая версия сборки использовалась для определенного класса узлов.

Как-то сначала не нужно перечислять все мое дерево, чтобы узнать, какие классы-узлы были использованы, добавить их в список известных типов и затем сериализовать.

И даже тогда мне нужно будет найти способ добавить раздел к информации о параметрах вывода данных для используемых классов.

Возможно, я единственный, у кого есть эта проблема, но я действительно надеюсь, что кто-то еще столкнулся с этой проблемой раньше и, возможно, с ее элегантным решением;) Я могу себе представить, что это не то, что может быть обработано стандартом .NET-сериализатор, но, возможно, есть сторонняя (бесплатная, с открытым исходным кодом даже?) Реализация?

+0

Кстати, я думаю, вы имели в виду «.NET Serializer», а не «C# Serializer». –

+0

Мои извинения, вы правы :) – Pygmy

ответ

0

Вы можете выполнить это с помощью BinaryFormatter или SoapFormatter. Эти форматы работают с произвольными объектными графами и обрабатывают любые объекты, с которыми они сталкиваются (пока типы объектов отмечены [Serializable]) и будут правильно сохранять циклические ссылки. Если вам интересно узнать, как объекты сериализуются, используйте SoapFormatter, который выведет XML.

Обратите внимание, что любые сборки, которые могут быть загружены по требованию, должны быть в GAC, иначе среда выполнения не найдет их.

Чтобы справиться с версиями, вы могли бы сделать что-то вроде этого:

[Serializable] 
public class SomeVersionedClass : IDeserializationCallback 
{ 
    private const int CURRENT_VERSION = 10; 

    private int version = CURRENT_VERSION; 

    void IDeserializationCallback.OnDeserialization(object sender) 
    { 
     if (version != CURRENT_VERSION) 
      throw new ApplicationException(
       "Mismatch between serialized data version " + version + 
       " and required version " + CURRENT_VERSION + "."); 
    } 
} 

Обратите внимание, что вы могли бы рассмотреть, вместо того, чтобы бросать исключение, перенос данных из предыдущей версии макета до новой версии. Кроме того, остерегайтесь того, что удаление сериализованных полей из класса будет полностью предотвращать последующую десериализацию, поэтому, если вы планируете разрешить миграцию из поля, которое больше не используется, вам придется покинуть это поле, чтобы предыдущие версии могли десериализоваться должным образом (и, конечно, чтобы вы могли получить данные, чтобы их перенести).

+0

Спасибо за ваш ответ, но можете ли вы каким-либо образом указать мне на любую страницу, объясняющую больше о том, как я реализую свои потребности (двунаправленные ссылки, управление версиями классов) с помощью этих? Мой 5-минутный Google kung-fu кажется слабым ... :) – Pygmy

+0

Двунаправленные и циклические ссылки будут обрабатываться прозрачно форматами; вам нечего делать, чтобы их сохранить. Я обновлю свой ответ, чтобы предоставить механизм для управления версиями. – cdhowie