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

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

Шрифт:

Связь сервиса с контекстом осуществляется путем задания соответствующего свойства контекста для данного контекста. Каждое свойство контекста имеет имя и содержит ссылку на некоторый объект, реализующий интерфейс IContextProperty.

Любой объект в данном контексте может по имени свойства получить доступ к соответствующему объекту-свойству и явно пользоваться всеми его возможностями (например, вызывать его методы). Такой способ явного использования контекста не очень интересен, т. к. он предполагает тесную связь между кодом компонента и кодом аспекта (сервиса, доступного через свойство контекста). При использовании чисто декларативного способа связывания компонента и аспекта необходимо обеспечить неявное связывание компонента с сервисом, когда в коде компонента нет никакого упоминания этого сервиса. Этого можно достигнуть за счет использования понятия перехвата.

Как уже упоминалось ранее, в случае пересечения вызовом границы контекста (кроме контекста по умолчанию), прокси на вызывающей стороне преобразует вызов в сообщение (объект, реализующий интерфейс IMessage), которое пройдя через цепочку перехватчиков (объектов, реализующих интерфейс IMessageSink), в вызываемом контексте вновь преобразуется в вызов, который исполняется соответствующим объектом. Результат отправляется вызывающей стороне через ту же цепочку перехватчиков.

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

ICcontributeObjectSink, IContributeServerContextSink, IContributeClientContextSink. Выбор одного из этих интерфейсов определяет ту цепочку перехватчиков, в конец которой будет добавлен новый перехватчик. На самом деле в контексте может существовать несколько цепочек перехватчиков:

• Одна цепочка перехватчиков, перехватывающих все вызовы поступающие ко всем объектам, живущим в данном контексте. Для встраивания перехватчика в эту цепочку объект-свойство контекста должен реализовать интерфейс IContributeServerContextSink.

• По одной цепочке к каждому объекту, живущему в контексте. В эту цепочку вызов попадает пройдя по цепочке общей для всего контекста. Для встраивания перехватчика в эту специфичную для объекта цепочку объект-свойство должен реализовать интерфейс IContributeObjectSink.

• Одна цепочка для всех вызовов, которые объекты контекста делают за пределы данного контекста. Для встраивания перехватчика в эту цепочку объект-свойство должен реализовать интерфейс IContributeClientContextSink.

После этих вводных замечаний о механизме работы атрибута и контекста перейдем к коду атрибута MyCallTraceAttribute и к комментариям к этому коду.

using System;

using System.10;

using System.Threading;

using System.Runtime.Remoting.Messaging;

using System.Runtime.Remoting.Contexts;

using System.Runtime.Remoting.Activation;

using System.Runtime.CompilerServices;

namespace SPbU.AOP_NET{

[AttributeUsage(AttributeTargets.Class)]

public class MyCaiiTraceAttribute: ContextAttribute,

IContributeServerContextSink {

private const String PROPERTY_NAME = "MyCallTrace";

private String _logFileName = null;

public MyCallTraceAttribute(String logFileName):

base(PROPERTY_NAME) {

if (logFileName == null) {

throw new ArgumentNullException("logFileName");

}

_logFileName = logFileName;

}

public override bool IsContextOK(Context ctx,

IConstructionCallMessage msg) {

if (ctx == null)

throw new ArgumentNullException("ctx");

if (msg == null)

throw new ArgumentNullException("msg");

MyCallTraceAttribute property =

(MyCallTraceAttribute)ctx.GetProperty(PROPERTY_NAME)

if ((property!= null) &&

(property._logFileName == _logFileName))

return true;

else

return false;

}

public override void GetPropertiesForNewContext {

IConstructionCallMessage ctorMsg) {

ctorMsg.ContextProperties.Add((IContextProperty) this);

}

public virtual IMessageSink GetServerContextSink {

IMessageSink nextSink) {

MyCallTraceServerContextSink propertySink =

new MyCallTraceServerContextSink(this, nextSink);

return (IMessageSink)propertySink;

}

[Methodlmpl(MethodImplOptions.Synchronized)]

internal void LogMessage(String msg){

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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