For example I have OnMethodBoundaryAspect
logger which I apply to iterator method:
public override void OnEntry(MethodExecutionArgs args) {
BeginMethodScope( args );
Logger.LogRequestEntry();
}
public override void OnSuccess(MethodExecutionArgs args) {
Logger.LogRequestSuccess();
}
public override void OnException(MethodExecutionArgs args) {
Logger.LogRequestError( args.Exception );
}
public override void OnExit(MethodExecutionArgs args) {
EndMethodScope( args );
}
If I use semantic advising:
OnEntry
is invoked when IEnumerable
is started.OnExit
is invoked when IEnumerable
is finished.If I use non-semantic advising:
OnEntry
/OnExit
is invoked before/after creation of IEnumerable
.But what if I want to use both ways at once? Because I want to log the method call itself (not iteration starting).
Maybe I can achieve this with low-level advices?
Yes, you can achieve this by creating two groups of advices within the same aspect, as shown in the example below.
[PSerializable]
public class MyAspect : MethodLevelAspect
{
[OnMethodEntryAdvice(SemanticallyAdvisedMethodKinds = SemanticallyAdvisedMethodKinds.None)]
[AdviceDependency(AspectDependencyAction.Order, AspectDependencyPosition.Before, nameof(OnEntrySemantic))]
[SelfPointcut]
public void OnEntry( MethodExecutionArgs args )
{
Console.WriteLine("OnEntry");
}
[OnMethodExitAdvice( Master = nameof( OnEntry ) )]
public void OnExit( MethodExecutionArgs args )
{
Console.WriteLine( "OnExit" );
}
[OnMethodEntryAdvice]
[SelfPointcut]
public void OnEntrySemantic( MethodExecutionArgs args )
{
Console.WriteLine( "OnEntrySemantic" );
}
[OnMethodExitAdvice( Master = nameof( OnEntrySemantic ) )]
public void OnExitSemantic( MethodExecutionArgs args )
{
Console.WriteLine( "OnExitSemantic" );
}
}
P.S. The current version of PostSharp will emit a build-time warning for the example above. This is due to a bug that should be fixed in one of the upcoming releases. The run-time behavior of the aspect is not affected.