Open sandboxFocusImprove this doc

LA0105: Pointcut Returns a Declaration That Cannot Be Found

Severity Error
Reported by PostSharp
Message Error while evaluating the MethodPointcut "<PointcutMethod>" on "<AspectTarget>": cannot find the <ReflectionType> "<Declaration>" in the current assembly or in the assemblies that it references.

Cause

A MethodPointcut selects the targets of an advice with a method of the aspect class. PostSharp runs this method at build time and maps each reflection object that it returns, such as a Type, a MethodInfo or a FieldInfo, to a declaration of the code model of the project. When it cannot find this declaration in the current assembly or in the assemblies that the project references, it reports LA0105 on the pointcut method and skips the object. Properties, events and parameters have their own messages, LA0103 and LA0104.

This happens when the pointcut method returns a declaration that exists only at build time, for instance an internal member of .NET: the pointcut method runs on the implementation assemblies of .NET, but the project compiles against reference assemblies, which contain only the public API. <ReflectionType> is the type of the reflection object, such as RuntimeMethodInfo for a method or RuntimeType for a type.

In the following example, the pointcut method returns a method of System.AppContextConfigHelper, an internal type of .NET.

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

namespace Errors.LA0105_Error;

[PSerializable]
public class LogMethodsAttribute : TypeLevelAspect
{
    // The pointcut method returns a method of System.AppContextConfigHelper, an internal type of .NET that the project cannot reference.
    private IEnumerable<MethodInfo> SelectMethods( Type type )
    {
        yield return typeof(object).Assembly.GetType( "System.AppContextConfigHelper", true )!
            .GetMethod( "GetBooleanConfig", BindingFlags.NonPublic | BindingFlags.Static, new[] { typeof(string), typeof(bool) } )!;
    }

    [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 LA0105: LA0105_Error.cs(14,37): Error while evaluating the MethodPointcut "Errors.LA0105_Error.LogMethodsAttribute.SelectMethods(System.Type)" on "Errors.LA0105_Error.OrderService": cannot find the RuntimeMethodInfo "Boolean GetBooleanConfig(System.String, Boolean)" in the current assembly or in the assemblies that it references.

Resolution

Return only declarations of the current assembly from the pointcut method, usually the members of the target type, which you get from its parameter. Advices can only modify the code of the current assembly.

In the following example, the pointcut method returns the methods that OrderService declares.

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

namespace Errors.LA0105_Fixed;

[PSerializable]
public class LogMethodsAttribute : TypeLevelAspect
{
    // The pointcut method returns the methods that the target type declares.
    private IEnumerable<MethodInfo> SelectMethods( Type type )
    {
        return 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