Как можно пререхватить событие десериализацыи ?
Есть довольно громоздкая и многоетажная структура данных с множеством перекресных ссылок между обектами.
(Случилось так изза того что сам объект проектирования дуалистичен и будет разсматриваться з двух сторон).
В самом низу етой структури данных лежат "атомарные" неизменяемые сущности которые хранятся в БД. Хотя сами они не большые но их очень много и они могут включаться в несколько разных объектов верхнего уровня.
Для економии памяти я не создаю ети атоми с помощю конструктора а с помощю фабрики. Фабрика смотрит есть ли у нее в кеше необходимый екземпляр и если есть то возвращает ссылку на него. Иначе создает.
Теперь появилась потребность клонировать обекты вехнего уровня структуры данных. Изза большого количества перекресных ссылок делать это поетажным клонированием полей объекта не получается (тоесть можно но очень сложно).
Решил сериализовать обетк верхнего уровня, а потом десиреализовать. Такой подход легче реализовать и корректность перекресных ссылок не пострадает. Но вот не задача. Атомарные объекты нижнего уровня создадутся в обход моей фабрики.
Вопрос. Можно ли моему десериализированому обекту както узнать что он только что десериализировался чтоб уничтожыть копии етих обектов-атомов и получить ссылки на их оригиналы у фабрики.
Ну тоесть можно ли както сделать так чтоб сразу после десериализацыи вызывался некий метод моих обектов. Знаю что в Джаве можно. а тут в .НЕТ не знаю.
Ну тоесть можно ли както сделать так чтоб сразу после десериализацыи вызывался некий метод моих обектов. Знаю что в Джаве можно. а тут в .НЕТ не знаю.
Можно. Только нужно не событие организовывать. Нужно помимо маркировки объекта атрибутом SerializableAttribute реализовывать интерфейс ISerializable (Джава? ;) Это кстати избавит вас от необходимости объвлять у объекта публичный конструктор без параметров.
В MSDN очень вменяемый пример был в статье про этот интерфейс - посмотрите.
[quote=MSDN]
[COLOR=blue]public[/COLOR] sealed [COLOR=blue]class[/COLOR] Singleton : ISerializable
{
...............................
[COLOR=green]// A method called when serializing a Singleton.[/COLOR]
[SecurityPermissionAttribute(SecurityAction.LinkDemand,
Flags=SecurityPermissionFlag.SerializationFormatter)]
[COLOR=blue]void[/COLOR] ISerializable.GetObjectData(
SerializationInfo info, StreamingContext context)
{
[COLOR=green]// Instead of serializing this object, [/COLOR]
[COLOR=green]// serialize a SingletonSerializationHelp instead.[/COLOR]
info.SetType(typeof(SingletonSerializationHelper));
[COLOR=green]// No other values need to be added.[/COLOR]
}
[COLOR=green]// Note: ISerializable's special constructor is not necessary [/COLOR]
[COLOR=green]// because it is never called.[/COLOR]
}
[Serializable]
internal sealed [COLOR=blue]class[/COLOR] SingletonSerializationHelper : IObjectReference
{
[COLOR=green]// This object has no fields (although it could).[/COLOR]
[COLOR=green]// GetRealObject is called after this object is deserialized.[/COLOR]
[COLOR=blue]public[/COLOR] Object GetRealObject(StreamingContext context)
{
[COLOR=green]// When deserialiing this object, return a reference to [/COLOR]
[COLOR=green]// the Singleton object instead.[/COLOR]
[COLOR=blue]return[/COLOR] Singleton.GetSingleton();
}
}
В
void[/COLOR] ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
Но мне не совсем такое надо. Мне нужно чтоб объект десериализировался стандартно, а потом ему передалось управление для того чтоб он мог себя поправить.
Вот нашел такое
[quote=codeproject.com]
public class MyBindingList<T> : BindingList<T>
{
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
.....................
}
}
Помойму то что мне надо. Поправте если ошибаюсь.
Фактически, ваша ситуация похожа на пример синглтоном.
При реализации интерфейса ISerializable нашим "атомом" в двоичный поток будет писаться объект-заглушка AtomSerializationHelper, который содержит нужные поля-значения оригинального объекта.
При десериализации атома из заглушки будут считываться реквизиты (например, поле-идентификатор id), по которым будет выполнен запрос к фабрике и вернется нормальный объект.
З.Ы. Изначально вопрос стоял не в сериализации системы, а в ее копировании (клонировании).
Возможно поможет эта ссылка http://forum.codenet.ru/showpost.php?p=154925&postcount=14
При реализации интерфейса ISerializable нашим "атомом" в двоичный поток будет писаться объект-заглушка AtomSerializationHelper, который содержит нужные поля-значения оригинального объекта.
При десериализации атома из заглушки будут считываться реквизиты (например, поле-идентификатор id), по которым будет выполнен запрос к фабрике и вернется нормальный объект.
Действительно. Ступил я чтото.
Возможно поможет эта ссылка http://forum.codenet.ru/showpost.php?p=154925&postcount=14
Весьма полезная для меня ссылка. Я подумаю о таком варианте. Хотя вряд ли его применю, поскольку мою сущность за период ее жызни (15-20 мин.) придется переодически бекапить защищаясь от сбоя. Думаю в етом случае тоже использовать сериализацыю. Так что пускай и копирование тоже так происходит.