| Severity | Error |
| Reported by | Metalama.Extensions.Interceptors |
| Message | The <Source> cannot intercept uses of members of '<Type>' because this type is introduced by an aspect. Uses of its members do not exist in the source code. |
Cause
Metalama.Extensions.Interceptors lets an aspect or a fabric replace the calls to selected methods with calls to other methods. An aspect or fabric registers an interceptor with the InterceptMethods method. The Type method of the registration builder selects the type that declares the intercepted methods.
Interceptors apply only to the calls that are written in the source code. A type that an aspect introduces doesn't exist in the source code, so no source code can contain a call to its methods.
Metalama reports LAMA1004 when the type given to Type is introduced by an aspect, for example the result of IntroduceClass. In the message, <Source> describes the aspect or fabric that made the registration, and <Type> is the introduced type.
In the following example, the aspect introduces the Printer class and then registers an interceptor for its Print method.
1using Metalama.Extensions.Interceptors;
2using Metalama.Framework.Aspects;
3using Metalama.Framework.Code;
4using System;
5using System.Linq;
6
7namespace Doc.LAMA1004.Error;
8
9internal class RedirectPrintsAttribute : TypeAspect
10{
11 public override void BuildAspect( IAspectBuilder<INamedType> builder )
12 {
13 var printer = builder.IntroduceClass( "Printer" ).Declaration;
14
15 // Error: the Printer class is introduced by this aspect, so its methods cannot be intercepted.
16 builder.InterceptMethods(
17 b => b
18 .Type( printer )
19 .Methods( "Print" )
20 .RedirectToExistingMethod( typeof(Interceptors).AsINamedType().Methods.OfName( "Print" ).Single() ) );
21 }
22}
23
24internal static class Interceptors
25{
26 public static void Print( string value ) => Console.WriteLine( "intercepted: " + value );
27}
28
1using System;
2
3namespace Doc.LAMA1004.Error;
4
5[RedirectPrints]
Error LAMA1004: The interceptor method 'Interceptors.Print(string)' registered by the aspect [RedirectPrintsAttribute] applied to 'Program' cannot intercept uses of members of 'Program.Printer' because this type is introduced by an aspect. Uses of its members do not exist in the source code.
6internal static partial class Program
7{
8 public static void Run() => Console.WriteLine( "Hello" );
9}
10
Resolution
Select a type that exists in the source code, or in a referenced assembly, as the declaring type of the intercepted methods. In the following example, the Printer class is declared in the source code and the aspect intercepts its Print method.
1using Metalama.Extensions.Interceptors;
2using Metalama.Framework.Aspects;
3using Metalama.Framework.Code;
4using System;
5using System.Linq;
6
7namespace Doc.LAMA1004.Fixed;
8
9internal class RedirectPrintsAttribute : TypeAspect
10{
11 public override void BuildAspect( IAspectBuilder<INamedType> builder )
12 {
13 // The Printer class is declared in the source code, so its methods can be intercepted.
14 builder.InterceptMethods(
15 b => b
16 .Type( typeof(Printer) )
17 .Methods( "Print" )
18 .RedirectToExistingMethod( typeof(Interceptors).AsINamedType().Methods.OfName( "Print" ).Single() ) );
19 }
20}
21
22internal static class Interceptors
23{
24 public static void Print( string value ) => Console.WriteLine( "intercepted: " + value );
25}
26
1using System;
2
3namespace Doc.LAMA1004.Fixed;
4
5internal static class Printer
6{
7 public static void Print( string value ) => Console.WriteLine( value );
8}
9
10[RedirectPrints]
11internal static class Program
12{
13 public static void Run() => Printer.Print( "Hello" );
14}
15
1using System;
2
3namespace Doc.LAMA1004.Fixed;
4
5internal static class Printer
6{
7 public static void Print(string value) => Console.WriteLine(value);
8}
9
10[RedirectPrints]
11internal static class Program
12{
13 public static void Run() => Interceptors.Print("Hello");
14}
15