Open sandboxFocusImprove this doc

LAMA0032: Several templates have the same name

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
Source Code
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
Transformed Code
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

See also