Поддержка АОП в Delphi

Можно ли использовать Aspect Oriented Programming в Delphi? Меня бы интересовала поддержка на родном языке, а также сторонние решения.

У меня нет конкретной проблемы, которую я хочу решить с AOP, но мне просто интересно изучить AOP.

Ответы

Ответ 1

АОП зависит от двух вещей:

  • Возможность ввода дополнительного кода в существующую единицу кода
  • Механизм размещения условий, в которых должен быть введен код.

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

Скомпилированные языки JIT имеют больше возможностей для реализации кодирования, чем статически скомпилированные программы, потому что в байт-кодексе/IL сохраняется дополнительная информация. Они также поддерживают отражение, которое позволяет управлять кодом во время выполнения.

Delphi.NET и Prism имеют тот же доступ к этим возможностям, что и любой другой язык .NET.

Есть две рамки AOP для Delphi Win32, о которых я знаю. Первый - MeAOP, о котором уже упоминалось. Второй - Infra. Оба проекта используют аналогичный подход к АОП. Они используют комбинацию RTTI и умных манипуляций с указателями для перехвата вызовов метода, поэтому вы можете запускать дополнительный код до или после вызова метода. Вы определяете свою сквозную функцию как подкласс класса AOP среды. Вы регистрируете методы, которые хотите перехватить, передав имя метода в виде строкового аргумента в структуру AOP.

Оба фреймворка по-прежнему активно развиваются и на самом деле больше по объему, чем просто АОП. К сожалению, документация несколько скудна (и в случае Infra в основном на португальском языке)

Другой проект предпринял попытку AOP посредством перекодировки исходного кода в 2004 году с некоторым успехом. В основном они построили аспектный инструмент поверх инструмента преобразования программ общего назначения под названием DMS и использовали его для ввода кода в файлы исходного текста delphi до компиляции. На их аспектно-ориентированный язык в первую очередь влиял AspectJ.

http://www.gray-area.org/Research/GenAWeave/ содержит ссылки на оригинальную бумагу и презентацию, а также некоторые видео процесса преобразования.

Также возможно использовать инструментарий кода времени исполнения для выполнения этого. Его метод, используемый некоторыми профайлерами для ввода счетчиков и трассировки стека в исполняемый код без изменения исходного источника. Аналогичный метод может быть использован для того, чтобы вводить сквозные задачи в статически скомпилированный исполняемый файл. Проект PinTool является хорошим примером этого.

Ответ 2

ClassHelpers в более поздних версиях Delphi допускают некоторый очень ограниченный тип поведения типа AOP. Вы можете использовать ClassHelpers, чтобы вводить поведение в другие классы, не сходя с них. Он позволяет переопределять существующие методы и затем необязательно вызывать этот существующий метод.

Ограничение - вы должны объявить ClassHelper для определенного класса и его потомков. Кроме того, класс может иметь только один ClassHelper.

Они похожи на методы расширения в С#.

Ответ 3

В библиотеке DSharp есть AOP:
https://bitbucket.org/sglienke/dsharp
Более подробную информацию можно найти по адресу: https://bitbucket.org/sglienke/dsharp

Также посмотрите TVirtualMethodInterceptor.
Это в RTL с Delphi 2010 и позволяет делать OnBefore, OnAfter и т.д. Вызывает все виртуальные методы в классе.
Этот вызов сам по себе должен охватывать необходимость того, что вам нужно, используя Rtti, а не плетение, которое намного быстрее, чем вовремя плетения.