Open sandboxFocusImprove this doc

LA0106: Pointcut Returns an Object That Is Not a Declaration

Severity Error
Reported by PostSharp
Message Error while evaluating the MethodPointcut "<PointcutMethod>" on "<AspectTarget>": the pointcut method returned an object of type "<ObjectType>", which is not a declaration. Return reflection objects such as Type, MethodInfo, FieldInfo, PropertyInfo, EventInfo, ParameterInfo or LocationInfo.

Cause

A MethodPointcut selects the targets of an advice with a method of the aspect class. This method can return an IEnumerable<T> of object, but each object that it returns must be the reflection object of a declaration: a Assembly, a Type, a MethodBase, a FieldInfo, a PropertyInfo, an EventInfo, a ParameterInfo or a LocationInfo. When the method returns another object, such as a string, PostSharp reports LA0106 on the pointcut method and skips the object.

The current version of PostSharp shows, in place of <ObjectType>, the type of the PostSharp declaration of the aspect target, such as TypeDefDeclaration, and not the type of the object that the pointcut method returned.

In the following example, the pointcut method returns the names of the methods.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;

namespace Errors.LA0106_Error;

[PSerializable]
public class LogMethodsAttribute : TypeLevelAspect
{
    // The pointcut method returns the names of the methods instead of the methods themselves.
    private IEnumerable<object> SelectMethods( Type type )
        => type.GetMethods( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly ).Select( method => method.Name );

    [OnMethodEntryAdvice, MethodPointcut( nameof(SelectMethods) )]
    public void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"Entering {args.Method.Name}." );
    }
}

[LogMethods]
public class OrderService
{
    public void PlaceOrder() => Console.WriteLine( "Order placed." );
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder();
    }
}
error LA0106: LA0106_Error.cs(15,33): Error while evaluating the MethodPointcut "Errors.LA0106_Error.LogMethodsAttribute.SelectMethods(System.Type)" on "Errors.LA0106_Error.OrderService": the pointcut method returned an object of type "String", which is not a declaration. Return reflection objects such as Type, MethodInfo, FieldInfo, PropertyInfo, EventInfo, ParameterInfo or LocationInfo.

Resolution

Return the reflection objects of the declarations instead of their names or of other values. Declaring the return type of the pointcut method with the reflection type, such as IEnumerable<MethodInfo>, lets the C# compiler catch the mistake.

In the following example, the pointcut method returns the MethodInfo objects of the methods.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;

namespace Errors.LA0106_Fixed;

[PSerializable]
public class LogMethodsAttribute : TypeLevelAspect
{
    // The pointcut method returns the MethodInfo objects of the methods.
    private IEnumerable<object> SelectMethods( Type type )
        => type.GetMethods( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly );

    [OnMethodEntryAdvice, MethodPointcut( nameof(SelectMethods) )]
    public void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"Entering {args.Method.Name}." );
    }
}

[LogMethods]
public class OrderService
{
    public void PlaceOrder() => Console.WriteLine( "Order placed." );
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder();
    }
}
Entering PlaceOrder.
Order placed.

See Also

Reference

MethodPointcut
OnMethodEntryAdvice

Other Resources

Selecting Members with Pointcuts
Advice Methods