| Severity | Error |
| Reported by | Metalama.Extensions.Interceptors |
| Message | The <Source> cannot generate the interceptor of the <Site> in the requested placement because <Reason>. The call site is left unchanged. |
Cause
An interceptor redirects the calls to a method to another method that Metalama generates from a template. The aspect chooses where the generated method goes with PlaceInCallingType, PlaceInType or PlaceInStaticClass, and can adjust the method in the Configure delegate. The call site must be able to call the method at that place.
Metalama reports LAMA1024 when the generated method can't be placed as requested for a call site, and it leaves the call site unchanged. The <Source> placeholder describes the template and the aspect, <Site> the intercepted call, and <Reason> the cause. The most common ones are:
- The accessibility that the
Configuredelegate assigns is more restrictive than the call site needs. For instance, a private method of another type can't be called. - The method is an instance method, but the call site has no
this(it's in a static method or in a conditional access), or the method isn't placed in the calling type or one of its base types. - The name given to
PlaceInStaticClassisn't a valid full class name, or the type given toPlaceInTypedoesn't exist. - The call site is in top-level statements, whose type can't be named, or the signature contains an anonymous type.
In the following example, the method is generated in Helpers and the Configure delegate makes it private, but the call is in Report.
1using Metalama.Extensions.Interceptors;
2using Metalama.Framework.Aspects;
3using Metalama.Framework.Code;
4using System;
5
6namespace Doc.LAMA1024.Error;
7
8public class InterceptPrintAttribute : TypeAspect
9{
10 public override void BuildAspect( IAspectBuilder<INamedType> builder )
11 => builder.InterceptMethods(
12 i => i
13 .Type( typeof(Printer) ).Methods( "Print" )
14 .RedirectToSynthesizedMethod( nameof(this.Intercept) )
15 .PlaceInType( typeof(Helpers) )
16 .Configure( b =>
17 {
18 // Error: a private method of Helpers cannot be called from Report.
19 b.Method.Accessibility = Accessibility.Private;
20 } ) );
21
22 [Template]
23 public dynamic? Intercept()
24 {
25 Console.Write( "> " );
26
27 return meta.Proceed();
28 }
29}
30
1using System;
2
3namespace Doc.LAMA1024.Error;
4
5public static class Printer
6{
7 public static void Print( string value ) => Console.WriteLine( value );
8}
9
10public static class Helpers { }
11
12[InterceptPrint]
13public static class Report
14{
Error LAMA1024: The interceptor template 'Intercept' registered by the aspect [InterceptPrintAttribute] applied to 'Report' cannot generate the interceptor of the call to 'Printer.Print(string)' in the requested placement because the accessibility Private of the interceptor method is more restrictive than the accessibility Internal that the call site needs. The call site is left unchanged.
15 public static void Run() => Printer.Print( "Hello" );
16}
17
Resolution
Read the reason in the message, and change the placement or the configuration of the aspect:
- Remove the accessibility assignment, or assign an accessibility that the call site can use.
- Place the method in the calling type with
PlaceInCallingType, where a private method is enough. - Make the method static if the call site has no
this. - Fix the type or class name given to
PlaceInTypeorPlaceInStaticClass.
In the following example, the method is internal, so Report can call it.
1using Metalama.Extensions.Interceptors;
2using Metalama.Framework.Aspects;
3using Metalama.Framework.Code;
4using System;
5
6namespace Doc.LAMA1024.Fixed;
7
8public class InterceptPrintAttribute : TypeAspect
9{
10 public override void BuildAspect( IAspectBuilder<INamedType> builder )
11 => builder.InterceptMethods(
12 i => i
13 .Type( typeof(Printer) ).Methods( "Print" )
14 .RedirectToSynthesizedMethod( nameof(this.Intercept) )
15 .PlaceInType( typeof(Helpers) )
16 .Configure( b =>
17 {
18 // Fixed: an internal method of Helpers can be called from Report.
19 b.Method.Accessibility = Accessibility.Internal;
20 } ) );
21
22 [Template]
23 public dynamic? Intercept()
24 {
25 Console.Write( "> " );
26
27 return meta.Proceed();
28 }
29}
30
1using System;
2
3namespace Doc.LAMA1024.Fixed;
4
5public static class Printer
6{
7 public static void Print( string value ) => Console.WriteLine( value );
8}
9
10public static class Helpers { }
11
12[InterceptPrint]
13public static class Report
14{
15 public static void Run() => Printer.Print( "Hello" );
16}
17
1using System;
2
3namespace Doc.LAMA1024.Fixed;
4
5public static class Printer
6{
7 public static void Print(string value) => Console.WriteLine(value);
8}
9
10public static class Helpers
11{
12 internal static void Printer_Print_Interceptor(string value)
13 {
14 Console.Write("> ");
15 Printer.Print(value);
16 }
17}
18
19[InterceptPrint]
20public static class Report
21{
22 public static void Run() => Helpers.Printer_Print_Interceptor(value: "Hello");
23}
24