Console.ReadLine();
Console.WriteLine("Bye");
}
}
}
И несколько комментариев. В .NET синхронизацию можно обеспечить либо с помощью критических секций, встраиваемых в код
компонента, либо декларативно с помощью контекста синхронизации. Последнее похоже на использование понятия активности в
COM+.
Привязка объекта к контексту позволяет использовать при работе с этим объектом различные сервисы (например, синхронизации,
поддержки транзакций и т.п.). Но
зато и обращаться к такому объекту извне его контекста можно только через прокси. Однако
это прозрачно для клиента, не нужно создавать и регистрировать какие-либо каналы (при работе в рамках одного домена
приложения). Если объект не привязан к контексту, то он располагается в специальном контексте по умолчанию. К контексту по
умолчанию
имеют прямой доступ все потоки, исполняемые в данном домене приложения.
Набор сервисов, доступных объектам привязанным к контексту, можно расширять вводя новые атрибуты и реализуя перехват
вызовов методов этих объектов. Подробнее эти важные вопросы будут рассмотрены в следующем разделе.
.NET и аспектно-ориентированное программирование
Введение
Говоря про компонентное программирование нельзя не упомянуть про парадигму аспектно-ориентированного программирования
(АОП). Элементы этой парадигмы встречаются в области технологии программирования уже достаточно давно. Это субъектно -
ориентированное программирование ( subject - oriented programming ) [SOP1, SOP2], композиционные фильтры ( composition
filters ) [CF1, CF2], адаптивное программирование ( adaptive programming ) [AP1, AP2]. В наиболее явной форме формулировка
данной парадигмы представлена в работе [AOP1]. Хороший обзор по АОП представлен в диссертации [AOP2]. И
, наконец, связи
между АОП и .NET отражены в статье [AOP3].
С точки зрения АОП в процессе разработки достаточно сложной системы программист решает две ортогональные задачи:
z Разработка компонентов
z Разработка сервисов, поддерживающих взаимодействие компонентов
Такие языки программирования как, например, C++, VB и т.п. ориентированы прежде всего на решение первой задачи. Код
компонента представляется в виде класса, т.е. он хорошо локализован и, следовательно, его легко просматривать, изучать,
модифицировать, повторно использовать. С другой стороны, при программировании процессов, в которые вовлечены различные
объекты
, мы получаем код, в котором элементы, связанные с поддержкой такого процесса, распределены по коду всей системы.
Эти элементы встречаются в коде множества классов, их совокупность в целом не локализована в обозримом сегменте кода. В
результате мы сталкиваемся с проблемой "запутанного" кода (code tangling).
В рамках АОП утверждается, что никакая технология проектирования не
поможет решить данную проблему, если только мы
будем оставаться в рамках языка, ориентированного только на разработку компонентов. Для программирования сервисов,
обеспечивающих взаимодействие объектов, нужны специальные средства, возможно специальные языки.
Понятие аспект в рамках АОП в диссертации [AOP2] определено так: "Некоторая модель является аспектом другой модели, если
она пересекает (crosscuts) ее структуру". Иными словами
понятие аспекта относительно. Если, например, в качестве модели
некоторой системы мы рассматриваем совокупность компонентов, представляющих такие сущности как вкладчик, счет, банк, то
аспектами являются сервисы, обеспечивающие синхронизацию доступа к счету, распределенные транзакции, безопасность. То
есть автоматически выполняемые сервисы, обеспечивающие слаженную, надежную, безопасную работу компонентов.
Итак, согласно парадигме АОП, для программирования
компонентов и аспектов нужны различные, специфические языки
программирования. После этапа кодирования компонентов и аспектов на соответствующих языках выполняется автоматическое
построение оптимизированного для выполнения (но не для просмотра и модификации) кода (например, на C). Этот финальный
процесс называется слиянием ( weaving ).
В рамках COM+ элементы идей АОП присутствуют в виде использования декларативного программирования для задания
сервисов
, услугами которых будут пользоваться компоненты. Сами компоненты разрабатываются на языках, ориентированных на
разработку компонентов (C++, VB). При конфигурировании компонента в COM+ приложении задается некоторый набор
атрибутов, определяющий тот набор сервисов, которыми будет пользоваться данный компонент.
В COM+ набор возможных сервисов и, соответственно, задающих их атрибутов, фиксирован. Программист не может разработать
новый сервис, который можно
было бы декларативно связать с некоторым компонентом, приписав последнему соответствующий
атрибут. Ситуация изменилась в .NET. Хотя и осталась возможность использовать все сервисы из COM+, появилась новая
возможность разработки новых сервисов, подключаемых к компонентам декларативно, посредством определения новых
атрибутов. Весь этот механизм основан на таких понятиях как контекст и пользовательский атрибут.
Прежде чем мы
перейдем к рассмотрению контекстов и атрибутов необходимо заметить, что в документации к .NET отсутствует
информация о ряде важнейших классов и интерфейсов, которые нам предстоит использовать. Указывается, что эти классы и
интерфейсы предназначены для использования самой системой (CLR), и что не предполагается их использование разработчиками
приложений. Тем не менее получить информацию об этих
классах и интерфейсах возможно. Имеются статьи (например, [AOP3]),
код, в которых демонстрируется использование данных классов и интерфейсов.
Важнейшим новым источником информации является опубликованный Microsoft весной 2002 года код объемом около 1.9 млн