Альтернативы XmlSerializer и OnSerializing / OnSerialized - PullRequest
1 голос
/ 24 марта 2010

У меня есть различные сложные объекты, которые часто имеют коллекции других сложных объектов. Иногда я хочу загружать коллекции только тогда, когда они нужны, поэтому мне нужен способ отслеживать, была ли коллекция загружена (ноль / пусто не обязательно означает, что она не была загружена). Для этого эти сложные объекты наследуются от класса, который поддерживает коллекцию загруженных коллекций. Затем нам просто нужно добавить вызов функции в установщике для каждой коллекции, которую мы хотим отслеживать, следующим образом:

public List<ObjectA> ObjectAList {
    get { return _objectAList; }
    set { 
        _objectAList = value; 
        PropertyLoaded("ObjectAList");
    }
}

Функция PropertyLoaded обновляет коллекцию, которая отслеживает, какие коллекции были загружены.

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

В идеале я хотел бы иметь возможность использовать OnSerializing / OnSerialized, чтобы функция знала, вызывается ли она законно, однако мы используем XmlSerializer, поэтому это не работает. Как бы мне ни хотелось перейти на использование DataContractSerializer, по разным причинам я не могу этого сейчас сделать.

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

1 Ответ

3 голосов
/ 24 марта 2010

XmlSerializer не поддерживает обратные вызовы сериализации. У вас есть несколько вариантов. Например, если вы хотите выбрать сериализацию свойства с именем ObjectAList, вы можете добавить метод:

public bool ShouldSerializeObjectAList () { /* logic */ }

Если вам нужно знать и во время десериализации, вы можете использовать:

[XmlIgnore]
public bool ObjectAListSpecified {
    get { /* logic whether to include it in serialization */ }
    set { /* logic to apply during deserialization */ }
}

(хотя вы можете обнаружить - я не уверен, что set вызывается только для случая true)

Другой вариант, конечно, заключается в реализации IXmlSerializable, но это следует делать только в крайнем случае. Это не весело.

...