Open sandboxFocusImprove this doc

LA0114: Method Interception Aspect Applied to a Static Constructor

Severity Error
Reported by PostSharp
Message Cannot apply the aspect "<Aspect>" to the static constructor of type "<Type>": a method interception aspect cannot be applied to a static constructor.

Cause

A MethodInterceptionAspect replaces the body of its target method with a call to OnInvoke. PostSharp does not support this transformation on a static constructor, which the runtime calls itself, and reports LA0114 instead of weaving the aspect.

Attribute multicasting never applies a MethodInterceptionAspect to a static constructor, because the aspect does not accept this kind of target. The message comes from code that chooses the targets itself: an IAspectProvider that provides the aspect to the type initializer, or an OnMethodInvokeAdvice whose pointcut selects a static constructor.

<Type> is the type that declares the static constructor. The message points to the declaration where the providing aspect is applied.

In the following example, the [LogStaticMembers] aspect provider adds the [Log] interception aspect to the static methods of Settings, and also to its static constructor.

using System;
using System.Collections.Generic;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.LA0114_Error;

[PSerializable]
public class LogAttribute : MethodInterceptionAspect
{
    public override void OnInvoke( MethodInterceptionArgs args )
    {
        Console.WriteLine( $"Calling {args.Method.Name}." );
        args.Proceed();
    }
}

// Logs the static methods of the target class.
[PSerializable]
public class LogStaticMembersAttribute : TypeLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
    {
        Type type = (Type) targetElement;

        foreach ( MethodInfo method in type.GetMethods( BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly ) )
        {
            yield return new AspectInstance( method, new LogAttribute() );
        }

        // The aspect provider also adds the interception aspect to the static constructor.
        if ( type.TypeInitializer != null )
        {
            yield return new AspectInstance( type.TypeInitializer, new LogAttribute() );
        }
    }
}

[LogStaticMembers]
public static class Settings
{
    private static readonly Dictionary<string, string> _values;

    static Settings()
    {
        _values = new Dictionary<string, string> { ["Currency"] = "EUR" };
    }

    public static string Get( string name ) => _values[name];
}

public static class Program
{
    public static void Main()
    {
        Console.WriteLine( Settings.Get( "Currency" ) );
    }
}
error LA0114: LA0114_Error.cs(41,21): Cannot apply the aspect "Errors.LA0114_Error.LogAttribute" to the static constructor of type "Errors.LA0114_Error.Settings": a method interception aspect cannot be applied to a static constructor.

Resolution

Provide the aspect to methods only: in the ProvideAspects method of the aspect provider, skip the type initializer and the other constructors. To run code when a type is initialized, call it from the static constructor itself.

In the following example, the aspect provider no longer adds the aspect to the static constructor.

using System;
using System.Collections.Generic;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.LA0114_Fixed;

[PSerializable]
public class LogAttribute : MethodInterceptionAspect
{
    public override void OnInvoke( MethodInterceptionArgs args )
    {
        Console.WriteLine( $"Calling {args.Method.Name}." );
        args.Proceed();
    }
}

// Logs the static methods of the target class.
[PSerializable]
public class LogStaticMembersAttribute : TypeLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
    {
        Type type = (Type) targetElement;

        // The aspect provider adds the interception aspect to methods only.
        foreach ( MethodInfo method in type.GetMethods( BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly ) )
        {
            yield return new AspectInstance( method, new LogAttribute() );
        }
    }
}

[LogStaticMembers]
public static class Settings
{
    private static readonly Dictionary<string, string> _values;

    static Settings()
    {
        _values = new Dictionary<string, string> { ["Currency"] = "EUR" };
    }

    public static string Get( string name ) => _values[name];
}

public static class Program
{
    public static void Main()
    {
        Console.WriteLine( Settings.Get( "Currency" ) );
    }
}
Calling Get.
EUR

See Also

Reference

MethodInterceptionAspect
IAspectProvider
AspectInstance

Other Resources

Intercepting Methods
Adding Aspects Programmatically Using IAspectProvider