| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot introduce an interface from the aspect "<Aspect>" applied to "<Target>" because the aspect is statically scoped. Derive the aspect from InstanceLevelAspect or implement IInstanceScopedAspect, and do not apply it to a static member. |
Cause
The target type of an interface introduction implements the interface by delegating each of its members to the aspect instance, so each object of the target type needs its own aspect instance. Such an aspect is instance-scoped: it implements IInstanceScopedAspect, as InstanceLevelAspect does, and is applied to a type or to a non-static member.
An aspect that does not implement IInstanceScopedAspect, such as a TypeLevelAspect, is statically scoped: it has a single instance for its whole target. When such an aspect introduces an interface with IntroduceInterfaceAttribute or an IntroduceInterfaceAdviceInstance, PostSharp reports LA0069. An instance-scoped aspect applied to a static member is statically scoped too.
<Target> is the declaration to which the aspect is applied: the target type, or the member whose declaring type receives the interface.
In the following example, the [Describable] aspect derives from TypeLevelAspect and introduces IDescribable into Customer.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0069_Error;
public interface IDescribable
{
string Describe();
}
[PSerializable]
[IntroduceInterface( typeof(IDescribable) )]
public class DescribableAttribute : TypeLevelAspect, IDescribable
{
public string Describe() => "Described by the aspect";
}
// The type-level aspect has a single instance for the class, so it cannot implement the interface for each object.
[Describable]
public class Customer
{
}
public static class Program
{
public static void Main()
{
IDescribable describable = (IDescribable) new Customer();
Console.WriteLine( describable.Describe() );
}
}
error LA0069: LA0069_Error.cs(22,14): Cannot introduce an interface from the aspect "Errors.LA0069_Error.DescribableAttribute" applied to "Errors.LA0069_Error.Customer" because the aspect is statically scoped. Derive the aspect from InstanceLevelAspect or implement IInstanceScopedAspect, and do not apply it to a static member.
Resolution
- Derive the aspect from InstanceLevelAspect instead of TypeLevelAspect.
- When the aspect must derive from another class, implement IInstanceScopedAspect.
- Do not apply the aspect to a static member.
In the following example, the aspect derives from InstanceLevelAspect, so each Customer has an aspect instance that implements IDescribable.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0069_Fixed;
public interface IDescribable
{
string Describe();
}
// An instance-level aspect has one instance for each object, which implements the introduced interface.
[PSerializable]
[IntroduceInterface( typeof(IDescribable) )]
public class DescribableAttribute : InstanceLevelAspect, IDescribable
{
public string Describe() => "Described by the aspect";
}
[Describable]
public class Customer
{
}
public static class Program
{
public static void Main()
{
IDescribable describable = (IDescribable) new Customer();
Console.WriteLine( describable.Describe() );
}
}
Described by the aspect
See Also
Reference
IntroduceInterfaceAttribute
InstanceLevelAspect
IInstanceScopedAspect
Other Resources
Introducing Interfaces, Methods, Properties and Events into Existing Classes