Страницы

пятница, 21 сентября 2012 г.

Revised Object Inspector для Delphi 2010-XE3 от Uwe Schuster. Обзор.

Этот пост является укороченным переводом описания первой версии Продвинутого Инспектора Объектов из блога Uwe.


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

На данный момент Revised Object Inspector поддерживает Delphi 2010, Delphi XE, XE2 и XE3. На 21 сентября 2012 года последней версией является Beta 6.

Автор эксперта: Uwe Schuster. Uwe также является активным разработчиком Version Insight Plus, Modal Search Dialog expert, Platforms Expert, IDE Compiler Utils, а также Jedi Version Control System.

См. также:

Вот так выглядит Revised Object Inspector. Отличия в закладке Favorites и строке фильтрации.

 Продвинутый Object Inspector

воскресенье, 16 сентября 2012 г.

Головокружительные возможности Dependency Injection и Delphi Spring. Часть 8. Разное.

Это перевод публикации Ника Ходжеса от 5 ноября 2011 года: Getting Giddy with Dependency Injection and Delphi Spring #8 – Miscellanea. (перевод сделан с разрешения автора).


Все переводы по Spring


Как обычно, Delphi Spring Framework можно скачать с GoogleCode.

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

  • Как вы наверно заметили, я призываю вас использовать интерфейсы при кодировании и регистрировать классы, реализующие эти интерфейсы в фреймворке. О чём я забыл упомянуть явно, это о том, что все интерфейсы, зарегистрированные в фреймворке Spring должны иметь GUID. GUID легко добавить, нажав CTRL+SHIFT+G в редакторе кода Delphi. А если же вы попробуете использовать интерфейс, у которого нет GUID-а, то получите ошибку: “Project <НазваниеПроекта>.exe raised exception class ERegistrationException with message 'Non-Guid Interface Services are not supported.” («Интерфейсы без Guid не поддерживаются»).
     
  • Если внимательно посмотреть на код в демонстрационных проектах, то можно заметить, что прежде чем что-либо делать с контейнером Spring, необходимо вызвать GlobalContainer.Build. Этот метод должен быть вызван до того, как что-либо может быть получено из ServiceLocator. Метод Build это код, который собирает воедино все зарегистрированные классы, создаёт экземпляры классов или подготавливает их к созданию по запросу, с учётом указанного времени жизни. Если при запуске приложения вы получаете ошибку 'LifetimeTypeManager was expected.', то это с большой вероятностью означает, что вам необходимо вызвать Build для вашего контейнера. И в самом деле, метод Build является основой вашего контейнера Внедрения Зависимостей. Вы должны один раз вызвать метод Build в корне вашего приложения. Для Delphi разработчиков это означает, что он должен быть вызван одной из первых строчек в вашем DPR-файле. Это также означает, что классы лучше регистрировать как можно раньше.
     
  • Вы не обязаны использовать Global Container и Service Locator предоставляемые вам фреймворком. Создание своих собственных вариантов более чем приветствуется. У нас в Gateway Ticketing мы сделали следующее: мы объявили интерфейс, являющийся полной абстракцией понятия Контейнер DI (DI Container = Контейнер Обращения Зависимостей), а затем реализовали этот интерфейс самостоятельно, используя наследника от Tcontainer из фреймворка Delphi Spring. Таким образом, если в фреймворке что-то изменяется (а он действительно меняется с тех самых пор, как мы начали его использовать) или, если мы решим использовать другой контейнер, наш код полностью отделён от какой-либо конкретной реализации. Ещё один хороший пример следования правилу «Пиши код для абстракций, а не реализации». :)
     
  • Я вынужден отметить, что некоторые считают концепцию Service Locator анти-паттерном . Сам я пока что ещё не пришёл к твёрдому заключению по этому вопросу. Да, Service Locator почти всегда является Одиночкой, но я лично и не рассматриваю одиночек только для чтения как что-то плохое, в отличие от некоторых. (Одиночка для чтения и для записи, по сути, является глобальной переменной, и я думаю, что все согласятся с тем, что глобальные переменные являются Порождением Сатаны.) Однако существуют некоторые разногласия в том, является ли использование контейнера реализацией Service Locator. Кроме того, если все зависимости определены до того, как результат выполнения станет доступным пользователю, то можно ли вообще считать контейнер переменной? Это остается предметом дискуссий. В конечном счете, для меня ценность и польза от Service Locator с лихвой перевешивает все возможные недостатки.
     
  • Существует один недостаток, возвращающий нас к предыдущему пункту, который заключается в том, что когда вещи настолько отделены друг от друга и позднее связывание настолько ярко выражено, то становится возможным успешно собрать программу и до самого её запуска так и не узнать о том, что мы забыли зарегистрировать необходимый реализующий класс. В сложной системе, может пройти немало времени, прежде чем кто-либо заметит, что отсутствует реализующий класс для какого-нибудь редко используемого интерфейса. Если вы следуете предложенному мной образцу регистрации реализации в initialization секции модуля, то вы обязаны использовать этот модуль где-нибудь в программе (примечание переводчика: включить в uses), чтобы регистрация сработала. Как уже говорилось, если вы забыли его добавить, и не включили этот модуль в свою программу, то компилятор вам ничего не скажет, и узнаете вы об этом только во время работы программы. Это слабое место, и вам следует быть очень внимательным, чтобы не попасться в эту ловушку. В качестве стратегии можно рассматривать выделение всех регистраций в единый модуль, или использовать что-то типа статического анализа кода, который проверит, что для каждого вызова GetService есть соответствующий вызов RegisterService (или как там эти методы у вас называются). Просто, чтобы вы были в курсе.

Это всего лишь несколько вещей, на которые стоит обратить внимание, при использовании Dependency Injection в вашем коде. Я говорил это раньше, я скажу это снова: Если вы не используете Dependency Injection, значит, вы работаете неправильно.


Ссылки по теме

пятница, 14 сентября 2012 г.

Lazy Delphi Builder 1.7.5.232 от 13-09-2012 для Delphi XE3

Lazy Delphi Builder XE3 Logo

Что нового (вкратце):

  • LazyDBP файлы сохранялись в Ansi кодировке. Теперь будут в UTF8.
  • Исправлен "бесконечный" List index out of bounds(-1) на 4й закладке.
  • Отправка мейла вместе со всеми логами и файлами прямо из программы
  • В дереве с файлами новый фильтр: показать только ошибочные пакеты и проекты.
  • Для консольной версии тихий режим /quiet
  • Много мелких улучшений в GUI и консольной версии (подробный список под катом, и в архиве с программой).

Скачивать на домашней странице: http://www.lazyproject.info/downloads/ или здесь

среда, 5 сентября 2012 г.

Lazy Delphi Builder 1.7.3.217 от 05-09-2012 для Delphi XE3

Что нового

  • Добавлена поддержка Delphi XE3.
  • Drag and drop. Теперь можно просто перетаскивать файлы и папки прямо в дерево из проводника.
  • Поддержка NameSpaces. В предыдущих версиях, при компиляции для Delphi XE2 можно было получить ошибку компилятора Fatal: F1026 File not found: 'Windows.dcu'" (мог быть и другой модуль). Чтобы эту ошибку обойти, нужно было добавить в dcc params строчку -NSSystem;System.Win;WinAPI;Vcl;Vcl.Imaging;Data. Теперь в диалог сборки добавлен отдельный редактор для NameSpaces.
  • Сборка проектов в отдельном потоке
  • Исправлены ошибки связанные с удалением файлов из дерева.

Скачивать на домашней странице: http://www.lazyproject.info/downloads/ или здесь