Вход/Регистрация
Интернет-журнал "Домашняя лаборатория", 2007 №6
вернуться

Журнал «Домашняя лаборатория»

Шрифт:

? Поле _logFileName используется свойством контекста для хранения имени файла, в который надо записывать данные о перехваченных вызовах.

? Конструктор атрибута принимает в качестве аргумента имя файла, которое и сохраняется в поле _logFileName. Если имя не задано, генерируется соответствующее исключение. В начале работы конструктора вызывается конструктор базового класса ContextAttribute, которому в качестве аргумента передается имя данного свойства контекста (MyCallTrace).

? Публичный виртуальный метод IsContextOK объявлен в интерфейсе IContextAttribute. Именно этот метод ответственен за определение пригодности заданного контекста _ctx (первый аргумент) для жизни объекта, требования которого заданы в сообщении ms g (второй аргумент).

Сообщение msg должно быть ссылкой на объект, реализующий интерфейс IConstructionCallMessage. Это сообщение представляет запрос на создание некоторого объекта. Тут нужно напомнить, что в .NET удаленные объекты активируются либо сервером, либо клиентом. Сообщение типа IConstructionCallMessage посылается от клиента на сервер именно во втором случае. Для этого клиент либо вызывает new, и тогда все требования относительно активации объекта берутся из конфигурационного файла, либо вызывает Activator.CreateInstance и передает все необходимые данные в аргументах. Это сообщение приходит на сервер, где активатор Activator его его обрабатывает и возвращает клиенту сообщение типа IConstructionReturnMessage. Последнее содержит информацию (objRef), достаточную для построения прокси к активируемому объекту.

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

Базовая реализация метода IsContextOK в классе ContextAttribute (согласно коду из SSCLI) возвращает true, если новый объект не привязан к контексту (IsContextful == false) или у контекста ctx имеется свойство, имя которого совпадает с именем данного свойства. В остальных случаях возвращается false.

В классе MyCallTraceAttribute виртуальный метод IsContextOK переопределяется (overide). Прежде всего генерируется исключение, если не задан контекст ctx или сообщение msg. Далее делается попытка получить в контексте ctx ссылку на его свойство с именем, хранящемся в константе PROPERTY_NAME, типа MyCallTraceAttribute. Если такое свойство контекста находится, и его поле _iogFileName хранит то же имя файла, что и текущее свойство, то контекст ctx признается подходящим для активации в нем экземпляра класса с атрибутом [MyCallTrace (х)], где х — Строка, равная строке, хранящейся _logFileName. В противном случае система выполнения (CLR) создаст новый контекст для активации в нем этого объекта.

Заметим, что при наличии нескольких атрибутов, приписанных классу, пригодность старого контекста для активации в нем нового экземпляра этого класса считается установленной, если вызовы метода IsContextOK для каждого атрибута возвратили true.

? Виртуальный метод GetPropertiesForNewContext объявлен в интерфейсе IContextAttribute. В качестве аргумента этот метод принимает сообщение ctorMsg типа IConstructionCallMessage. Данный метод вызывается средой выполнения CLR если контекст, из которого был сделан запрос на активацию объекта, не удовлетворяет его требованиям (вызов IsContextOK вернул false). Здесь мы включаем в сообщение ctorMsg ссылку на объект, который будет играть роль нового свойства контекста — (IContextProperty) this. Благодаря этой ссылке все объекты, которые будут жить в новом контексте, смогут пользоваться данным свойством контекста, вызывая явно в своем коде его методы и свойства.

? Метод GetServerContextSink объявлен в интерфейсе IContributeServerContextSink и не имеет реализации в классе ContextAttribute. Этот метод должен вернуть ссылку на объект, реализующий интерфейс IMessageSink, т. е. на перехватчик, который будет подключен в конец существующей цепочки перехватчиков, через которую идут все вызовы в данный контекст. Единственным аргументом является ссылка nextSink на конец имеющейся в данный момент цепочки перехватчиков. В данной реализации этого метода формируется экземпляр класса MyCallTraceServerContextSink, который будет прокомментирован ниже.

Ссылка на этот экземпляр (новый перехватчик) и возвращается как результат вызова GetServerContextSink.

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

? Последний метод (LogMessage) класса MyCallTraceAttribute является внутренним для сборки и будет вызываться из класса MyCallTraceServerContextSink. Данный метод обеспечивает запись переданной в качестве аргумента строки в конец файла с именем, хранящемся в поле _logFileName свойства типа MyCallTraceAttribute с именем MyCallTrace текущего контекста. Объекты, живущие в данном контексте, могут вызывать этот метод явно в своем коде, получив ссылку на это свойство контекста по его имени. Однако в данном примере будет продемонстрировано использование свойства контекста в стиле аспектно-ориентированного программирования. Поэтому метод LogMessage будет в нашем случае вызываться перехватчиком, а не самим объектом, получившим вызов.

Реализации метода LogMessage весьма не эффективна. При каждом вызове этого метода файл открывается для записи в конец, производится запись и файл закрывается. Для обеспечения потокобезопасности весь метод включается в критическую секцию, препятствующую параллельному выполнению этого метода несколькими потоками. Для этого методу приписан атрибут [MethodImpl(MethodImplOptions. Synchronized)].

Цикл

while (logFile == null) {

logFile = File. AppendText(_logFileName);

  • Читать дальше
  • 1
  • ...
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: