XML сериализация интерфейсов - PullRequest
1 голос
/ 06 февраля 2012

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

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

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

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

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

Ответы [ 4 ]

2 голосов
/ 06 февраля 2012

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

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

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

var serializer = new XmlSerializer(myBaseType, arrayOfConcreteImplementations);

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

1 голос
/ 06 февраля 2012

Прочтите ваше сообщение от geekswithblogs.net. Я предложу вам сделать двоичную сериализацию. Это легко реализовать и поддерживать (если только вы не измените квалифицированное имя класса). Binary 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 голосов
/ 06 февраля 2012

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

0 голосов
/ 06 февраля 2012

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

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