| Severity | Error |
| Reported by | Metalama.Framework |
| Message | Only one template or advice attribute is allowed on a declaration, the member it overrides, and its containing property or event, but '<Attribute>' is applied to '<Declaration>' and '<OtherAttribute>' is applied to '<OtherDeclaration>'. |
Cause
Attributes such as TemplateAttribute and IntroduceAttribute mark a member of an aspect as a template and tell Metalama how to use it. An advice attribute like [Introduce] already makes the member a template, so the two can't be combined.
Metalama reports LAMA0261 when it finds more than one such attribute for the same member. It considers the attributes of the member itself and also:
- the attributes of the member it overrides, for instance the
[Template]attribute of OverrideMethodAspect.OverrideMethod; - for an accessor, the attributes of the containing property or event.
In the message, <Declaration> and <OtherDeclaration> are the declarations that carry the attributes <Attribute> and <OtherAttribute>.
The diagnostic is reported even if the aspect file doesn't import the Metalama.Framework namespaces with a using directive.
In the following example, the OverrideMethod method of the Log aspect has the [Template] attribute, although the method it overrides, OverrideMethodAspect.OverrideMethod, already has it.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0261.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 // Error: the base method is already a template, so [Template] is redundant.
9 [Template]
Error LAMA0261: Only one template or advice attribute is allowed on a declaration, the member it overrides, and its containing property or event, but 'TemplateAttribute' is applied to 'LogAttribute.OverrideMethod()' and 'TemplateAttribute' is applied to 'OverrideMethodAspect.OverrideMethod()'.
10 public override dynamic? OverrideMethod()
11 {
12 Console.WriteLine( $"Executing {meta.Target.Method}." );
13
14 return meta.Proceed();
15 }
16}
17
1namespace Doc.LAMA0261.Error;
2
3internal class Calculator
4{
5 [Log]
6 public int Add( int a, int b ) => a + b;
7}
8
Resolution
Keep only one attribute:
- When you override a template method of a base class, such as OverrideMethod, don't add a template or advice attribute to the override: it inherits the attribute of the base method, as in the following example.
- To introduce a member into the target type, use [Introduce] alone, without [Template].
- To use a member as a template that you pass to an advice method, use
[Template]alone, without an advice attribute. - Don't add an attribute to an accessor if the containing property or event already has one.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0261.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 // Fixed: the override inherits the [Template] attribute of the base method.
9 public override dynamic? OverrideMethod()
10 {
11 Console.WriteLine( $"Executing {meta.Target.Method}." );
12
13 return meta.Proceed();
14 }
15}
16
1namespace Doc.LAMA0261.Fixed;
2
3internal class Calculator
4{
5 [Log]
6 public int Add( int a, int b ) => a + b;
7}
8
1using System;
2
3namespace Doc.LAMA0261.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