Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как можно пререхватить событие десериализацыи ?

276
09 апреля 2008 года
Rebbit
1.1K / / 01.08.2005
Судьба заставила писать проект на С#, а я в нем .... Посему простите если вопрос глупый.

Есть довольно громоздкая и многоетажная структура данных с множеством перекресных ссылок между обектами.
(Случилось так изза того что сам объект проектирования дуалистичен и будет разсматриваться з двух сторон).
В самом низу етой структури данных лежат "атомарные" неизменяемые сущности которые хранятся в БД. Хотя сами они не большые но их очень много и они могут включаться в несколько разных объектов верхнего уровня.
Для економии памяти я не создаю ети атоми с помощю конструктора а с помощю фабрики. Фабрика смотрит есть ли у нее в кеше необходимый екземпляр и если есть то возвращает ссылку на него. Иначе создает.

Теперь появилась потребность клонировать обекты вехнего уровня структуры данных. Изза большого количества перекресных ссылок делать это поетажным клонированием полей объекта не получается (тоесть можно но очень сложно).
Решил сериализовать обетк верхнего уровня, а потом десиреализовать. Такой подход легче реализовать и корректность перекресных ссылок не пострадает. Но вот не задача. Атомарные объекты нижнего уровня создадутся в обход моей фабрики.

Вопрос. Можно ли моему десериализированому обекту както узнать что он только что десериализировался чтоб уничтожыть копии етих обектов-атомов и получить ссылки на их оригиналы у фабрики.
Ну тоесть можно ли както сделать так чтоб сразу после десериализацыи вызывался некий метод моих обектов. Знаю что в Джаве можно. а тут в .НЕТ не знаю.
5
09 апреля 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Rebbit
Вопрос. Можно ли моему десериализированому обекту както узнать что он только что десериализировался чтоб уничтожыть копии етих обектов-атомов и получить ссылки на их оригиналы у фабрики.
Ну тоесть можно ли както сделать так чтоб сразу после десериализацыи вызывался некий метод моих обектов. Знаю что в Джаве можно. а тут в .НЕТ не знаю.


Можно. Только нужно не событие организовывать. Нужно помимо маркировки объекта атрибутом SerializableAttribute реализовывать интерфейс ISerializable (Джава? ;) Это кстати избавит вас от необходимости объвлять у объекта публичный конструктор без параметров.
В MSDN очень вменяемый пример был в статье про этот интерфейс - посмотрите.

276
10 апреля 2008 года
Rebbit
1.1K / / 01.08.2005
Правильно ли я понял (с английским туго прошу не пинать)
[quote=MSDN]
Код:
[Serializable]
[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();
    }
}
[/quote]

В
 
Код:
[COLOR=blue]
void[/COLOR] ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
Указиваем кто будет десериализировать наш обект. И в примере фактически десериализацыи не происходит, а возвращается действующий синглетон.

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

Вот нашел такое

[quote=codeproject.com]
 
Код:
[Serializable]
    public class MyBindingList<T> : BindingList<T>
    {
        [OnDeserialized]
        private void OnDeserialized(StreamingContext context)
        {
           .....................
        }
    }
[/quote]
Помойму то что мне надо. Поправте если ошибаюсь.
5
11 апреля 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Rebbit
Для економии памяти я не создаю ети атоми с помощю конструктора а с помощю фабрики. Фабрика смотрит есть ли у нее в кеше необходимый екземпляр и если есть то возвращает ссылку на него. Иначе создает.

Фактически, ваша ситуация похожа на пример синглтоном.
При реализации интерфейса ISerializable нашим "атомом" в двоичный поток будет писаться объект-заглушка AtomSerializationHelper, который содержит нужные поля-значения оригинального объекта.
При десериализации атома из заглушки будут считываться реквизиты (например, поле-идентификатор id), по которым будет выполнен запрос к фабрике и вернется нормальный объект.


З.Ы. Изначально вопрос стоял не в сериализации системы, а в ее копировании (клонировании).
Возможно поможет эта ссылка http://forum.codenet.ru/showpost.php?p=154925&postcount=14

276
11 апреля 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: hardcase
Фактически, ваша ситуация похожа на пример синглтоном.
При реализации интерфейса ISerializable нашим "атомом" в двоичный поток будет писаться объект-заглушка AtomSerializationHelper, который содержит нужные поля-значения оригинального объекта.
При десериализации атома из заглушки будут считываться реквизиты (например, поле-идентификатор id), по которым будет выполнен запрос к фабрике и вернется нормальный объект.


Действительно. Ступил я чтото.

Цитата: hardcase
З.Ы. Изначально вопрос стоял не в сериализации системы, а в ее копировании (клонировании).
Возможно поможет эта ссылка http://forum.codenet.ru/showpost.php?p=154925&postcount=14


Весьма полезная для меня ссылка. Я подумаю о таком варианте. Хотя вряд ли его применю, поскольку мою сущность за период ее жызни (15-20 мин.) придется переодически бекапить защищаясь от сбоя. Думаю в етом случае тоже использовать сериализацыю. Так что пускай и копирование тоже так происходит.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог