2015-03-02 3 views
2

Есть ли способ обернуть вызов метода с помощью PostSharp? Мне нужно добавить код вокруг/вне определенного вызова.Метод вызова Wackping с PostSharp

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

Пример: Без аспекта:

... 
call(); 
... 

С аспектом:

beforePart(); 
call(); 
afterPart(); 
+1

Почему вы не можете использовать MethodInterceptionAspect.OnInvoke (MethodInterceptionArgs арг) и поставить перед и после того, как вокруг арг. Продолжить? – RagtimeWilly

+0

Я вызываю синхронизированный метод, и похоже, что Aspect также синхронизирован, если я использую MethodInterceptionAspect. Но код аспект не должен быть синхронизирован. – Ehler

+0

Если ваша программа синхронизирована, вы можете обернуть все методы с помощью postsharp, но только хотите, хотите ли вы, когда условие действительно, например логическое значение, и установите условие true при вызове метода beforePart() и установите значение false при вызове afterPart(). –

ответ

0

В настоящее время, единственный сценарий, в котором PostSharp ткет аспект вокруг места вызова, когда вы применяете этот аспект к способу в ссылочной сборке.

При применении аспекта в проекте вы можете установить имя внешней сборки в свойстве AttributeTargetAssemblies.

[Log(AttributeTargetAssemblies = "SomeLibrary", ...)] 

PostSharp, конечно, не будет изменять существующую внешнюю сборку, вместо этого он будет плести аспект сборки вашего проекта вокруг звонков ссылочной сборки.

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

Возможно, мы сможем решить эту проблему, если вы предоставите более подробную информацию о синхронизированном методе и почему невозможно использовать перехват метода.

Обновление.

Возможным обходным путем является введение блокировок синхронизации с использованием аспектов. Вы можете написать обычай OnMethodBoundaryAspect или использовать SynchronizedAttribute из библиотеки шаблонов Threading.

Затем вы можете использовать Aspect Dependency or Aspect Priority, чтобы убедиться, что измерение аспекта введено перед аспектом резьбы. Таким образом, поведение будет таким же, как при введении аспекта измерения вокруг сайта вызова.

[Serializable] 
[AspectTypeDependency(AspectDependencyAction.Order, 
         AspectDependencyPosition.Before, 
         typeof(SynchronizedAttribute))] 
public class MeasureTimeAttribute : OnMethodBoundaryAspect 
{ 
    // ... 
} 
+0

Я хочу измерить время выполнения (включая время ожидания или время сна) определенных методов. Для этого я сохраняю время ввода метода end end «event». Как вы сказали, во внешних сборках он работает идеально, но в синхронизированных методах в локальном проекте я не могу измерить время, которое происходит за счет блокировки или синхронизации из-за этих блокировок. – Ehler

+0

Вы вводите эти блокировки синхронизации, используя также аспекты? Или это просто написанный вручную код синхронизации? – AlexD

+0

Эти блокировки синхронизации вручную добавляются атрибутом '[MethodImpl (MethodImplOptions.Synchronized)]'. – Ehler

0

У меня было аналогичное требование, и я написал аспект регистрации для всех вызовов базы данных, которые я делаю с помощью внешней библиотеки, которая является Dapper. Я создал аспект:

[MulticastAttributeUsage(MulticastTargets.Method)] 
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] 
public sealed class SqlLogger : MethodInterceptionAspect 
{ 
    public override void OnInvoke(MethodInterceptionArgs args) 
    { 
     // logging code goes here 

     base.OnInvoke(args); 
    } 
} 

А потом я зарегистрировал его на уровне сборки:

[assembly: SqlLogger(AttributeTargetAssemblies = "Dapper", AttributePriority = 1)]