| Severity | Error |
| Reported by | PostSharp |
| Message | Error when applying the aspect "<Aspect>": Cannot find the declaration "<Declaration>" in the current assembly or in the assemblies that it references. |
Cause
An aspect that implements IAspectProvider adds aspects to other declarations by returning AspectInstance objects from its ProvideAspects method. The target element of each AspectInstance is a reflection object, which PostSharp maps back to a declaration of the code that it compiles. When the target element is a type, a method or a field that PostSharp cannot find in the current assembly or in the assemblies that the project references, it reports LA0033 on the aspect provider class.
This happens when the reflection object does not describe the code that you compile, but an implementation detail of the .NET runtime that no reference assembly exposes. The most common mistake is to call GetType() on the target element: the target element of a type-level aspect is already a Type, so GetType() returns System.RuntimeType, the internal class of reflection objects.
In the following example, the [Entity] aspect is meant to add the [Describable] aspect to Customer, but it provides it to System.RuntimeType.
using System;
using System.Collections.Generic;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0033_Error;
[PSerializable]
public class DescribableAttribute : InstanceLevelAspect
{
[IntroduceMember]
public string Describe() => $"Instance of {this.Instance!.GetType().Name}";
}
[PSerializable]
public class EntityAttribute : TypeLevelAspect, IAspectProvider
{
public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
{
// GetType() returns the type of the reflection object, System.RuntimeType, instead of the target class.
Type type = targetElement.GetType();
yield return new AspectInstance( type, new DescribableAttribute() );
}
}
[Entity]
public class Customer
{
}
public static class Program
{
public static void Main()
{
// The method introduced into Customer is not visible at compile time, so it is called with the dynamic keyword.
dynamic customer = new Customer();
Console.WriteLine( customer.Describe() );
}
}
error LA0033: LA0033_Error.cs(17,14): Error when applying the aspect "Errors.LA0033_Error.DescribableAttribute": Cannot find the declaration "System.RuntimeType" in the current assembly or in the assemblies that it references.
Resolution
Use the target element itself: cast it to Type in a type-level aspect, or to MethodBase in a method-level aspect, instead of calling GetType(). Provide aspects only to declarations of the current assembly, which are the only ones that PostSharp can transform.
In the following example, the provider casts the target element to Type, and the Describe method is introduced into Customer.
using System;
using System.Collections.Generic;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0033_Fixed;
[PSerializable]
public class DescribableAttribute : InstanceLevelAspect
{
[IntroduceMember]
public string Describe() => $"Instance of {this.Instance!.GetType().Name}";
}
[PSerializable]
public class EntityAttribute : TypeLevelAspect, IAspectProvider
{
public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
{
// The target element of a type-level aspect is the target class itself.
Type type = (Type) targetElement;
yield return new AspectInstance( type, new DescribableAttribute() );
}
}
[Entity]
public class Customer
{
}
public static class Program
{
public static void Main()
{
// The method introduced into Customer is not visible at compile time, so it is called with the dynamic keyword.
dynamic customer = new Customer();
Console.WriteLine( customer.Describe() );
}
}
Instance of Customer
See Also
Reference
IAspectProvider
AspectInstance
Other Resources
Adding Aspects Dynamically
Adding Aspects Programmatically Using IAspectProvider