Помощь и информация об аспектно-ориентированном программировании - PullRequest
17 голосов
/ 18 февраля 2009

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

  • Стоит ли мне исследовать этот путь АОП для этих ограниченных целей?
  • Какие платформы .NET, поддерживающие AOP, доступны?
  • Какие из этих платформ поддерживают свободный интерфейс (мне не нравится конфигурация XML):)

Ответы [ 5 ]

23 голосов
/ 18 февраля 2009

Аспектно-ориентированное программирование - это гораздо больше, чем просто ведение журнала, отчетности и так далее, как вы увидите, заглянув на веб-сайт PostSharp. Лично я не делал так много статического IL-ткачества, в основном динамического генерирования IL-кода для создания перехватчиков AOP, и при этом я в основном использовал его для обертывания и перехвата разрешений из инверсии контейнеров управления.

AOP может улучшить обработку исключений, улучшить трассировку, улучшить перехват транзакций.

Например,

NHibernate имеет своего рода AOP, хотя он статичен во время компиляции с точки зрения простых обработчиков событий; но для определенных событий в движке вы можете прикрепить перехватчики (иначе говоря, события, являющиеся точечными сокращениями и т. д.) - я использую это для внедрения, используя бизнес-объекты IoC в мои доменные объекты.

Мощные AOP-структуры позволяют обобщать, а еще более мощные - обобщать без накладных расходов во время выполнения; в принципе у вас есть несколько разных способов сделать это :

(0). (не совсем) "препроцессорные" AOP шаблоны в C ++, ifdefs и т. д.

  1. Отражение "АОП"
  2. IL-генерация во время выполнения через Reflection.Emit, требует высокого доверия. Это путь к DynamicProxy2 в проекте Castle. DynamicProxy2 довольно хорош, и в него ушло много работы! Кроме того, afaik PatternsAndPractices Policy Framework также использует этот подход, с большим количеством XML, хотя и со своим собственным генератором. NHibernate зависит от DynProx2.
  3. Для IL-компиляции + Assembly.Load (...) во время выполнения с использованием System.CodeDom.Compiler, а затем загрузка созданных сборок требует высокого доверия. Также возможна компиляция с любым другим компилятором, таким как Boo.Compiler, поскольку он создает «глобальные сборки функций», которые вы можете вызывать «по сценарию», но теперь мы немного выходим из AOP.
  4. Профилировщики API (не спрашивайте меня о них)
  5. Опираясь на среду выполнения: расширение MarshalByRef / ContextBoundObject см. Ссылку и использование инфраструктуры удаленного взаимодействия в .Net для выполнения AOP, что довольно сложно и вводит зависимости, которые вам могут не понадобиться.
  6. Посткомпиляция статического IL-ткачества, PostSharp и Mono.Cecil имеет эквивалент Reflection.Emit, но в этом нет ошибок для вызовов виртуальных методов в конкретных подклассах (если я правильно помню), таких как Reflection.Emit и с удовольствием проверит ваш код, похожий на Assembly.ReflectionOnlyLoad, а также позволит вам выводить IL-операции в этот код. Это хороший кандидат, если вы ищете подход довольно низкого уровня; не требует такого высокого доверия.
  7. Добавление точек расширения в ваш управляемый код для неуправляемых обратных вызовов в C / C ++ через p / invoke, но это требует некоторой мысли, поскольку исключения не пересекают границы памяти m / um счастливо (скорее, это испортит ваше приложение) , и если вы не используете VC ++ / C # в Windows с каркасом управляемых исключений, это может привести к серьезной ошибке. Вы можете передавать обратный вызов в C и p / invoke в C из C # и, вероятно, передавать обратные вызовы из C в C #, а также до тех пор, пока вы определяете делегат в C #. Точки расширения, вероятно, должны были бы быть сделаны посредством статического или динамического IL-ткача + точечные сокращения.

Использование в транзакциях Взгляните на Castle.Facilities.AutomaticTransactionManagement.TransactionFacility , чтобы найти хороший способ обработки транзакций с использованием AOP и возможности перехвата DynamicProxy2. Средство транзакций, интегрированное с System.Transcations и System.EnterpriseServices, заключается в том, что вы используете распределенный координатор транзакций (COM-компонент) для управления транзакциями. Кроме того, есть несколько примеров p / invoke в ядро, чтобы позаботиться о TxF и TxR компонентах Vista-kernel (aka Server 2008) , которые позволяют вам использовать транзакции в NTFS и в реестре. Таким образом, убедитесь, что CRUD, который вы делаете, является ACID, который также хорошо интегрируется с System.Transactions для создания вложенных транзакций.

Использование в инвариантной проверке Вы также можете использовать их для проектирования по контракту, добавив некоторые атрибуты к вашим параметрам.

public void PerformOperation([NotNull, NotEmpty] string value) {
// use string
[NotNull] return new string(' ', 5); // can return with attributes as well
}

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

Если вы хотите получить аксиоматические доказательства, взгляните на Sing # / Spec #, поскольку это более формально, и работа выполняется компилятором.

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

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

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

Другие рамки Если вам интересно узнать больше об АОП в целом, я предлагаю вам ознакомиться с презентациями Рикарда Эберга о Qi4J , это очень хорошая среда в Java для АОП (хотя java имеет немного другую объектно-наследуемую семантику, хотя и делает маленький хитрый бит для использования в C # / F # / Nermle / Boo, что угодно.

AOP + AddIns Еще одна интересная возможность использования аспектно-ориентированного программирования с созданными во время выполнения сборками, такими как создаваемые dynamicproxy2, заключается в том, что вы также можете использовать их для переноса объектов, которые пересекают границы приложения, тем самым упрощая создание надстройки в конвейере. Я втайне надеялся, что Microsoft воспользуется этим, когда создаст свою платформу AddIn для 3.5, но, к сожалению, они решили пойти статическим путем генерации кода, что привело к довольно большим затратам на создание надстроек для разработчика. Проблема заключается в том, что тип, загруженный для «больше, чем отражение», в AppDomain не может быть снова выгружен, если не выгружен весь AppDomain, поэтому вам нужно 1) отразить на плагине, не загружая его, чтобы увидеть, на что он способен, если вы позволяете писать или генерировать множество ручных метаданных (и в это верите) и 2) некоторый объект, чтобы держать дескриптор вашего объекта, чтобы он не был GCed, и вы не знаете тип (отсюда сборка IContract и AddInHandle-class) - это, вероятно, можно сделать хорошим способом с помощью динамического прокси / AOP.

Использование AOP для глобальной сборки мусора ... в распределенной системе, работающей на linux / windows в инфраструктуре общего языка. Бумагу было сложно загрузить, поэтому Я загрузил ее на свой сервер , поэтому я знаю, где она находится.

Post Scriptum (Если вы используете нестандартный язык в CLR, а не IL-ткачество DLR, может создать нестандартный код. Я думаю, что это особенно интересно для F #, потому что использование много не стандартный код для большой пользы языка (говорят кортежи) - вы можете пометить вашу сборку с помощью [assembly: CLSCompliant], если хотите получать предупреждения об этом во время компиляции.)

2 голосов
/ 18 февраля 2009

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

Одним из примеров является проектирование по контракту . Допустим, у вас есть несколько методов, к которым вы хотите применить некоторые общие контракты. Вы можете добавить некоторые «рекомендации» (термин AOP) до и после вызова каждого метода, не добавляя его в каждый метод.

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

Просто следите за тем, как реализованы аспекты. Некоторые реализации представляют собой сложные препроцессоры, которые могут усложнить отладку вашего кода. Другие плавно переходят на язык. Динамические языки очень хорошо справляются с AOP. Perl имеет Aspect.pm для AOP и более общий Hook :: LexWrap для выполнения перехватов методов.

1 голос
/ 18 февраля 2009

Если вы собираетесь взглянуть на Post Sharp, вы можете загрузить Google Book Downloader из CodePlex. Я думаю, что этот проект использует его.

1 голос
/ 18 февраля 2009

АОП мне тоже интересно. Мне кажется, что ведение журнала и мониторинг производительности, составление отчетов - это во многом то, для чего предназначен AOP. Для .NET Post Sharp является очень хорошей основой для АОП.

Я только немного экспериментировал с этим, но, похоже, он очень хорошо реализован.

0 голосов
/ 18 февраля 2009

Не думайте, что это что-то совершенно другое. АОП улучшает (IMO) ваш дизайн, уменьшая сцепление, увеличивая сплоченность, разделяя проблемы, возлагая на объект определенного типа 1 единственную ответственность. Если вы из мира .net, PostSharp использует пользовательские атрибуты для создания советов. Если вы из мира Java, вы можете использовать расширение Java под названием AspectJ . АОП имеет больше приложений, чем вы видите в целом.

...