| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The class '<ClassName>' defines several templates named '<TemplateName>'. Template names must be unique. |
Cause
Metalama identifies templates by their name, for instance when you pass a template name to an advice method like Override. Therefore, the names of the templates of a class must be unique. Template methods can't be overloaded: two template methods with the same name are ambiguous even if their parameters are different.
Metalama reports LAMA0032 when the class <ClassName> defines more than one template named <TemplateName>. The error is reported on the second template, and the compile-time code of the project isn't built.
In the following example, the aspect defines two Log templates, one without parameters and one with a category parameter.
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3using System;
4
5namespace Doc.LAMA0032.Error;
6
7public class LogAttribute : MethodAspect
8{
9 public string? Category { get; set; }
10
11 public override void BuildAspect( IAspectBuilder<IMethod> builder )
12 {
13 if ( this.Category == null )
14 {
15 builder.Override( "Log" );
16 }
17 else
18 {
19 builder.Override( "Log", args: new { category = this.Category } );
20 }
21 }
22
23 [Template]
24 private dynamic? Log()
25 {
26 Console.WriteLine( $"Executing {meta.Target.Method}." );
27
28 return meta.Proceed();
29 }
30
31 // Error: two templates cannot have the same name, even with different parameters.
32 [Template]
Error LAMA0032: The class 'LogAttribute' defines several templates named 'Log'. Template names must be unique.
33 private dynamic? Log( [CompileTime] string category )
34 {
35 Console.WriteLine( $"{category}: executing {meta.Target.Method}." );
36
37 return meta.Proceed();
38 }
39}
40
1namespace Doc.LAMA0032.Error;
2
3internal class Calculator
4{
5 [Log]
6 public int Add( int a, int b ) => a + b;
7
8 [Log( Category = "Math" )]
9 public int Multiply( int a, int b ) => a * b;
10}
11
Resolution
Give each template a unique name, and update the template names passed to the advice methods. In the following example, the second template is renamed LogWithCategory.
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3using System;
4
5namespace Doc.LAMA0032.Fixed;
6
7public class LogAttribute : MethodAspect
8{
9 public string? Category { get; set; }
10
11 public override void BuildAspect( IAspectBuilder<IMethod> builder )
12 {
13 if ( this.Category == null )
14 {
15 builder.Override( "Log" );
16 }
17 else
18 {
19 builder.Override( "LogWithCategory", args: new { category = this.Category } );
20 }
21 }
22
23 [Template]
24 private dynamic? Log()
25 {
26 Console.WriteLine( $"Executing {meta.Target.Method}." );
27
28 return meta.Proceed();
29 }
30
31 // Fixed: each template has a unique name.
32 [Template]
33 private dynamic? LogWithCategory( [CompileTime] string category )
34 {
35 Console.WriteLine( $"{category}: executing {meta.Target.Method}." );
36
37 return meta.Proceed();
38 }
39}
40
1namespace Doc.LAMA0032.Fixed;
2
3internal class Calculator
4{
5 [Log]
6 public int Add( int a, int b ) => a + b;
7
8 [Log( Category = "Math" )]
9 public int Multiply( int a, int b ) => a * b;
10}
11
1using System;
2
3namespace Doc.LAMA0032.Fixed;
4
5internal class Calculator
6{
7 [Log]
8 public int Add(int a, int b)
9 {
10 Console.WriteLine("Executing Calculator.Add(int, int).");
11 return a + b;
12 }
13
14 [Log(Category = "Math")]
15 public int Multiply(int a, int b)
16 {
17 Console.WriteLine("Math: executing Calculator.Multiply(int, int).");
18 return a * b;
19 }
20}
21