Open sandboxFocusImprove this doc

LA0048: Custom Pointcut Type Is Not Supported

Severity Error
Reported by PostSharp
Message Cannot find a weaver for the pointcut of type "<PointcutType>" used on "<Advice>". Use one of the pointcut types of PostSharp, such as MulticastPointcut or MethodPointcut, instead of a custom type.

Cause

A pointcut is a custom attribute that selects the declarations to which an advice of an aspect applies. PostSharp evaluates each pointcut type that it defines, such as MulticastPointcut and MethodPointcut. The base class Pointcut is public, but deriving from it does not create a new kind of pointcut: PostSharp cannot evaluate the derived type, and reports LA0048.

<PointcutType> is the custom pointcut type, and <Advice> is the advice method that uses it. The message is reported on the declaration of the pointcut class, not on the advice.

PostSharp then ignores the custom pointcut. When the advice has no other pointcut, it applies to the target of the aspect itself, and PostSharp also reports LA0049 if the advice cannot apply to this kind of declaration, for example an OnMethodEntryAdvice in an aspect applied to a class.

In the following example, the OnEntry advice of the [Trace] aspect uses a custom PublicMethodsPointcut attribute.

using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;

namespace Errors.LA0048_Error;

// A custom pointcut type. PostSharp only knows how to evaluate the pointcut types that it defines.
public sealed class PublicMethodsPointcut : Pointcut
{
}

[PSerializable]
public class TraceAttribute : TypeLevelAspect
{
    // PostSharp cannot evaluate PublicMethodsPointcut.
    [OnMethodEntryAdvice]
    [PublicMethodsPointcut]
    public void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"Entering {args.Method.Name}." );
    }
}

[Trace]
public class OrderService
{
    public void PlaceOrder( string product ) => Console.WriteLine( $"Order placed for {product}." );
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "coffee" );
    }
}
error LA0048: LA0048_Error.cs(19,17): Cannot find a weaver for the pointcut of type "Errors.LA0048_Error.PublicMethodsPointcut" used on "Errors.LA0048_Error.TraceAttribute.OnEntry(PostSharp.Aspects.MethodExecutionArgs)". Use one of the pointcut types of PostSharp, such as MulticastPointcut or MethodPointcut, instead of a custom type.

Resolution

Use a pointcut type of PostSharp:

  • MulticastPointcut selects members by kind, name and attributes, such as visibility.
  • MethodPointcut calls a method of the aspect that returns the declarations, for any selection logic that you write in C#.

In the following example, a MulticastPointcut selects the public instance methods of the target class.

using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Extensibility;
using PostSharp.Serialization;

namespace Errors.LA0048_Fixed;

[PSerializable]
public class TraceAttribute : TypeLevelAspect
{
    // MulticastPointcut is a pointcut type of PostSharp, which selects the public instance methods here.
    [OnMethodEntryAdvice]
    [MulticastPointcut( Targets = MulticastTargets.Method, Attributes = MulticastAttributes.Public | MulticastAttributes.Instance )]
    public void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"Entering {args.Method.Name}." );
    }
}

[Trace]
public class OrderService
{
    public void PlaceOrder( string product ) => Console.WriteLine( $"Order placed for {product}." );
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "coffee" );
    }
}
Entering PlaceOrder.
Order placed for coffee.

See Also

Reference

Pointcut
MulticastPointcut
MethodPointcut

Other Resources

Selecting Members with Pointcuts