| Severity | Error |
| Reported by | PostSharp |
| Message | Error while evaluating the MethodPointcut "<PointcutMethod>" on "<AspectTarget>": cannot find the property or event "<Member>" of type "<DeclaringType>" in the current assembly or in the assemblies that it references. The pointcut method must return properties and events of the current assembly. |
Cause
A MethodPointcut selects the targets of an advice with a method of the aspect class. PostSharp runs this method at build time, for each declaration to which the aspect applies, and maps each PropertyInfo or EventInfo that it returns to a property or an event of the code model of the project. When it cannot find the declaring type <DeclaringType> or the member <Member> in the current assembly or in the assemblies that the project references, it reports LA0103 on the pointcut method and skips the member.
This happens when the pointcut method returns a member 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. <PointcutMethod> is the pointcut method, and <AspectTarget> is the declaration to which the aspect applies.
Even when PostSharp finds the member, advices can only modify the code of the current assembly, so a pointcut method must return the properties and events of the current assembly.
In the following example, the pointcut method returns a property of System.SR, 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.LA0103_Error;
[PSerializable]
public class LogPropertyReadsAttribute : TypeLevelAspect
{
// The pointcut method returns a property of System.SR, an internal type of .NET that the project cannot reference.
private IEnumerable<PropertyInfo> SelectProperties( Type type )
{
yield return typeof(object).Assembly.GetType( "System.SR", true )!
.GetProperty( "Arg_ArgumentException", BindingFlags.NonPublic | BindingFlags.Static )!;
}
[OnLocationGetValueAdvice, MethodPointcut( nameof(SelectProperties) )]
public void OnGetValue( LocationInterceptionArgs args )
{
args.ProceedGetValue();
Console.WriteLine( $"Read {args.LocationName}: {args.Value}." );
}
}
[LogPropertyReads]
public class Customer
{
public string Name { get; set; } = "Alice";
}
public static class Program
{
public static void Main()
{
_ = new Customer().Name;
}
}
error LA0103: LA0103_Error.cs(14,39): Error while evaluating the MethodPointcut "Errors.LA0103_Error.LogPropertyReadsAttribute.SelectProperties(System.Type)" on "Errors.LA0103_Error.Customer": cannot find the property or event "System.String Arg_ArgumentException" of type "System.SR" in the current assembly or in the assemblies that it references. The pointcut method must return properties and events of the current assembly.
Resolution
Return only the properties and events of the current assembly from the pointcut method, usually those of the target type. Use BindingFlags.DeclaredOnly to leave out the members that the target type inherits from types of other assemblies.
In the following example, the pointcut method returns the properties that Customer declares.
using System;
using System.Collections.Generic;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0103_Fixed;
[PSerializable]
public class LogPropertyReadsAttribute : TypeLevelAspect
{
// The pointcut method returns the properties that the target type declares.
private IEnumerable<PropertyInfo> SelectProperties( Type type )
{
return type.GetProperties( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly );
}
[OnLocationGetValueAdvice, MethodPointcut( nameof(SelectProperties) )]
public void OnGetValue( LocationInterceptionArgs args )
{
args.ProceedGetValue();
Console.WriteLine( $"Read {args.LocationName}: {args.Value}." );
}
}
[LogPropertyReads]
public class Customer
{
public string Name { get; set; } = "Alice";
}
public static class Program
{
public static void Main()
{
_ = new Customer().Name;
}
}
Read Name: Alice.
See Also
Reference
MethodPointcut
OnLocationGetValueAdvice
Other Resources