2012-02-06 3 views
1

Мне нужно сериализовать сложные объекты в моем проекте и поместить их в базу данных. Я хотел бы сериализовать их с помощью XML для получения более легкой отладки моего приложения.XML-сериализация интерфейсов

Мой случай очень похож на то, что описано в этой статье: http://geekswithblogs.net/SoftwareDoneRight/archive/2008/01/16/how-to-serialize-an-interface-using-the-xmlserializer.aspx

Поэтому у меня есть объект, содержащий свойство, тип определяется интерфейсом. Тогда у меня есть разные конкретные типы, реализующие его.

Следуя подходу статьи, используя атрибут XmlInclude, я получаю сильное сопряженное решение, но мое приложение структурировано для использования подключаемого подхода, поэтому я мог бы иметь так много реализаций, сколько захочу от моего интерфейса.

Есть ли способ решить мою проблему, используя сериализацию xml, или мне нужно выполнить двоичную сериализацию?

ответ

1

Прочитать ваше сообщение от geekswithblogs.net. Я предлагаю вам выполнить двоичную сериализацию. Его легко реализовать и поддерживать (если только вы не измените квалифицированное имя класса). Binary Serializer также сериализует закрытых членов.

Как использовать двоичный Serializer

/// <summary> 
/// Serializes the given object to byte stream 
/// </summary> 
public sealed class Serializer { 
    /// <summary> 
    /// Serializes the given object to byte stream 
    /// </summary> 
    /// <param name="objectToSeralize">Object to be serialized</param> 
    /// <returns>byte array of searialize object</returns> 
    public static byte[] Serialize(object objectToSeralize) { 
     byte[] objectBytes; 
     using (MemoryStream stream = new MemoryStream()) { 
      //Creating binary formatter to serialize object. 
      BinaryFormatter formatter = new BinaryFormatter(); 

      //Serializing objectToSeralize. 
      formatter.Serialize(stream, objectToSeralize); 
      objectBytes = stream.ToArray(); 
     } 
     return objectBytes; 
    } 
    /// <summary> 
    /// De-Serialize the byte array to object 
    /// </summary> 
    /// <param name="arrayToDeSerialize">Byte array of Serialize object</param> 
    /// <returns>De-Serialize object</returns> 
    public static object DeSerialize(byte[] arrayToDeSerialize) { 
     object serializedObject; 
     using (MemoryStream stream = new MemoryStream(arrayToDeSerialize)) { 
      //Creating binary formatter to De-Serialize string. 
      BinaryFormatter formatter = new BinaryFormatter(); 

      //De-Serializing. 
      serializedObject = formatter.Deserialize(stream); 
     } 
     return serializedObject; 
    } 
} 
+0

Я думаю, что я буду использовать двоичную сериализацию, как вы sugest. Можете ли вы рассказать мне, какие классы я должен использовать? (Я никогда не делал этого с помощью .NET ...) – davioooh

+0

@DavidC. Я обновил свой ответ. –

+0

Отлично! Огромное спасибо! :) +1 – davioooh

0

XmlSerializer не поддерживает сериализацию интерфейсов. Но вы можете использовать Serializer Data Contract Serializer вместо того, чтобы украсить ваше свойство атрибутом KnownType.

+0

Я никогда не использовал атрибут «KnownType», но, быть еще одним ** с высокой связью ** решением моей проблемы ... – davioooh

+0

Может ли ваш интерфейс также реализовать IXmlS erializable? Вам нужно будет реализовать ReadXml и WriteXml в каждом типе, но его можно реализовать во втором классе с помощью XmlSerializer. – Huusom

0

Я решил эту проблему, включая метод SerializeMyself в интерфейсе. Я не знаю, было ли это самое элегантное решение ... но это сработало для меня.

+1

Это работа вокруг. Вы сериализуете объект самостоятельно, как предлагается в блоге geekswithblogs. Если это сработает для вас отлично. –

2

Если вы хотите использовать XmlSerializer вам необходимо иметь базовый класс, не интерфейс.

XmlInclude - это всего лишь один способ рассказать сериализатору о возможных реализациях. Другой подход - фактически передать включенные типы в сериализатор.

Просто перечислить все типы в вашем приложении, которые являются производными от базового класса (с помощью отражения) и передавать их в сериализатор как массив известных типов:

var serializer = new XmlSerializer(myBaseType, arrayOfConcreteImplementations); 

точно так же, вы можете сделать с DataContractSerializer: второй параметр - это набор известных типов, которые вы можете найти с помощью отражения), но с его помощью вы можете поддерживать интерфейсы ...

+0

Я думаю, что ваше решение не полностью разрешает мою проблему ... Я мог бы рекурсивно иметь объекты, содержащие «свойства абстрактного типа»: один объект содержит абстрактное свойство, которое в дополнение содержит абстрактное свойство ... и так далее. .. – davioooh

Смежные вопросы