Open sandboxFocusImprove this doc

LA0013: Aspect Class Is Private or Protected

Severity Error
Reported by PostSharp
Message The aspect class <AspectType> has <Visibility> visibility. It should have at least internal visibility.

Cause

PostSharp generates code that stores, deserializes and calls the aspect instances, outside of the class that declares the aspect. The aspect class must therefore be accessible from anywhere in the assembly: it must be public or internal. C# lets you apply a nested class as an attribute in its containing class, even when the nested class is private or protected, so the compiler does not catch the problem, and PostSharp reports LA0013 on the aspect class.

<Visibility> is private for a private nested class, and family for a protected one.

In the following example, the [Log] aspect is a private class nested in OrderService.

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

namespace Errors.LA0013_Error;

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

    // The aspect class is private, so the code that PostSharp generates cannot access it.
    [PSerializable]
    private class LogAttribute : OnMethodBoundaryAspect
    {
        public override void OnEntry( MethodExecutionArgs args )
        {
            Console.WriteLine( $"Entering {args.Method.Name}." );
        }
    }
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "Coffee" );
    }
}
error LA0013: LA0013_Error.cs(17,19): The aspect class Errors.LA0013_Error.OrderService.LogAttribute has private visibility. It should have at least internal visibility.

Resolution

Make the aspect class internal or public, or move it out of the containing class. A protected internal nested class is also accepted.

In the following example, the aspect class is internal.

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

namespace Errors.LA0013_Fixed;

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

    // The aspect class is internal, so the code that PostSharp generates can access it.
    [PSerializable]
    internal class LogAttribute : OnMethodBoundaryAspect
    {
        public override void OnEntry( MethodExecutionArgs args )
        {
            Console.WriteLine( $"Entering {args.Method.Name}." );
        }
    }
}

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

See Also

Other Resources

Developing Custom Aspects