| Severity | Error |
| Reported by | PostSharp |
| Message | Error in ImportMemberAdviceInstance provided by the IAdviceProvider implementation of aspect "<Aspect>" applied to "<TargetType>": imported location "<Location>" is not declared in the target type of the aspect. |
Cause
An aspect that implements IAdviceProvider can import a field or a property of its target class by giving its LocationInfo to an ImportLocationAdviceInstance. The aspect accesses this location on the instance of the target class, so the location must be declared in the target class, <TargetType>, or in one of its base classes. PostSharp reports LA0138 when <Location> is declared in another class.
This typically happens when ProvideAdvices(object) looks up the field or property in a fixed class instead of the target that it receives: the aspect works on this class and fails on the others. PostSharp reports the message on the aspect class.
In the following example, the [TraceCreation] aspect always imports the Name property of Customer, also when it is applied to Supplier.
using System;
using System.Collections.Generic;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Reflection;
using PostSharp.Serialization;
namespace Errors.LA0138_Error;
[PSerializable]
public class TraceCreationAttribute : InstanceLevelAspect, IAdviceProvider
{
[PNonSerialized]
public ILocationBinding? Name;
public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
{
FieldInfo aspectField = typeof(TraceCreationAttribute).GetField( nameof(this.Name) )!;
// The property belongs to Customer, also when the aspect is applied to Supplier.
PropertyInfo nameProperty = typeof(Customer).GetProperty( "Name" )!;
yield return new ImportLocationAdviceInstance( aspectField, new LocationInfo( nameProperty ) );
}
public override void RuntimeInitializeInstance()
{
Console.WriteLine( $"Created {this.Instance!.GetType().Name} {this.Name!.GetValue( this.Instance )}" );
}
}
[TraceCreation]
public class Customer
{
public string Name { get; set; } = "Alice";
}
[TraceCreation]
public class Supplier
{
public string Name { get; set; } = "Contoso";
}
public static class Program
{
public static void Main()
{
_ = new Customer();
_ = new Supplier();
}
}
error LA0138: LA0138_Error.cs(12,14): Error in ImportMemberAdviceInstance provided by the IAdviceProvider implementation of aspect "Errors.LA0138_Error.TraceCreationAttribute" applied to "Errors.LA0138_Error.Supplier": imported location "Errors.LA0138_Error.Customer.Name" is not declared in the target type of the aspect.
Resolution
Look up the imported field or property in the target of the aspect, which ProvideAdvices(object) receives as a Type. When a target may lack the field or property, skip the advice for this target instead of designating the field or property of another class.
In the following example, the aspect imports the Name property of each class to which it is applied.
using System;
using System.Collections.Generic;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Reflection;
using PostSharp.Serialization;
namespace Errors.LA0138_Fixed;
[PSerializable]
public class TraceCreationAttribute : InstanceLevelAspect, IAdviceProvider
{
[PNonSerialized]
public ILocationBinding? Name;
public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
{
FieldInfo aspectField = typeof(TraceCreationAttribute).GetField( nameof(this.Name) )!;
// The property is looked up in the target class of the aspect.
PropertyInfo nameProperty = ((Type) targetElement).GetProperty( "Name" )!;
yield return new ImportLocationAdviceInstance( aspectField, new LocationInfo( nameProperty ) );
}
public override void RuntimeInitializeInstance()
{
Console.WriteLine( $"Created {this.Instance!.GetType().Name} {this.Name!.GetValue( this.Instance )}" );
}
}
[TraceCreation]
public class Customer
{
public string Name { get; set; } = "Alice";
}
[TraceCreation]
public class Supplier
{
public string Name { get; set; } = "Contoso";
}
public static class Program
{
public static void Main()
{
_ = new Customer();
_ = new Supplier();
}
}
Created Customer Alice
Created Supplier Contoso
See Also
Reference
IAdviceProvider
ImportLocationAdviceInstance
LocationInfo
Other Resources
Providing Advices Dynamically
Accessing Members of the Target Class