Версионность сериализованных данных

Сложность 100-200

Во время изучения событийных систем и CQRS, поднимается вопрос о том, что надо каким-то образом читать и преобразовывать старые данные (как правило сериализованные в xml или json) к текущему состоянию системы, которая скорее всего изменилась со времени запуска. На самом деле проблема восстановления данных, чаще всего каких-либо настроек, весьма остро порой встает перед разработчиками. Т.е. у нас есть некоторое приложение, которое было уже доставлено конечному пользователю, и нам надо изменить формат сохранения настроек, сообщений. Если смотреть на проблему очень поверхностно, то обычно читаются настройки в старом формате, руками преобразуются в новый формат и сохраняются уже в новом виде.

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

На написание статьи и кода меня сподвигло наличие свободного времени (в меньшей части) и тот ужас, что я увидел в проекте коллег (в большей части). Или, если выразиться политкорректно то, код был чрезмерно раздут для задачи использовался не оптимально. Я думаю, что лучше один раз увидеть, чем сто раз прочитать.

На примере ниже сохраняются и восстанавливаются настройки расположения клиентских настроек для MDI приложения. Именно от того, что надо работать с любой версией настроек и было применено ручное составление и разбор XML файла. В доказательство можно привести проверку на внутреннюю версию файла. Хотя… что-то я смотрю и вижу, что старые версии не восстанавливаются, йехъ.

01

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

Подробнее

Self-Tracking Objects

Сложность 400

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

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

Подробнее

Автообнаружение и регистрация классов в StructureMap

Уровень подготовки по шкале MS: 400

Некоторое время назад  я рассказывал про чудесный IoC\DI контейнер StructureMap. На тот момент я описал основные приемы работы, скорее как справочник, показавший возможности, без углубления в конкретные темы. На этот раз я хочу рассказать о возможности автоматического обнаружения и регистрации классов средствами StructureMap.

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

Дальнейшие примеры покажут, как работать с обнаружением только по интерфейсу\базовому классу, а так же как работать при именовании классов по соглашениям (Convention over Configuration).

Вводная

Сначала достаточно простой пример. Пусть у нас есть множество классов для трансляции данных из базы, все они наследованы от базового класса. Т.е. что-то в духе:

 

И таких классов достаточно много, всех их регистрировать вручную не очень хочется, т.к. это выглядит ужасно в коде и писать долго. Регистрация таких адаптеров может занять экран, а то и два. Гораздо лучше поднапрячь извилины и записать это в несколько строк.

Итак, StructureMap предоставляет метод Scan, который пробегает по интересующим нас сборкам или папкам и регистрирует подходящие объекты. Для того чтобы метод Scan нашел и зарегистрировал типы необходимо соблюдение нескольких условий:

  • Тип должен быть явным, дженерик типы не регистрируются автоматически;
  • Тип должен иметь публичный конструктор;
  • Конструктор не может иметь аргументов примитивных типов;
  • Множественное регистрирование не допускается.

Указание сборки для сканирования можно задать несколькими способами:

  • Явно прописать имя сборки или же передать ее саму;
  • Обратиться к вызывающей сборке;
  • Найти сборку содержащую определенный тип;
  • Найти сборки по определенному пути.