Open sandboxFocusImprove this doc

LAMA0045: A live template aspect must have a parameterless constructor

Severity Error
Reported by Metalama.Framework
Message The class '<Type>' must have a parameterless constructor because of the [EditorExperienceAttribute(SuggestAsLiveTemplate = true)] attribute.

Cause

When you set the SuggestAsLiveTemplate property of the EditorExperienceAttribute to true, the IDE offers to apply the aspect as a live template, that is, to write the aspect's output directly into the source code. To do this, Metalama must create an instance of the aspect without any argument, because there's no custom attribute from which it could read constructor arguments.

Metalama reports LAMA0045 when the aspect class can't be instantiated this way: it doesn't have a constructor without parameters. The option is inherited, so the check also applies to classes derived from an aspect class that has this attribute. Abstract aspect classes are exempt, because they can't be instantiated: an abstract base aspect can carry the attribute to make all its derived aspects live templates, and each concrete derived aspect must then have a parameterless constructor. When the error is reported, the aspect isn't applied anywhere in the project.

In the following example, the Log aspect is offered as a live template, but its only constructor requires a category.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0045.Error;
5
6// Error: a live template needs a parameterless constructor, but this aspect has none.
7[EditorExperience( SuggestAsLiveTemplate = true )]
Error LAMA0045: The class 'LogAttribute' must have a parameterless constructor because of the [EditorExperienceAttribute(SuggestAsLiveTemplate = true)] attribute.

8public class LogAttribute : OverrideMethodAspect
9{
10    private readonly string _category;
11
12    public LogAttribute( string category )
13    {
14        this._category = category;
15    }
16
17    public override dynamic? OverrideMethod()
18    {
19        Console.WriteLine( $"[{this._category}] Executing {meta.Target.Method}." );
20
21        return meta.Proceed();
22    }
23}
24
1namespace Doc.LAMA0045.Error;
2
3internal class OrderService
4{
5    [Log( "Orders" )]
6    public void PlaceOrder( string customerId ) { }
7}
8

Resolution

Do one of the following:

  • Add a parameterless constructor to the aspect class. To keep aspect parameters, turn them into properties with default values, which users can still set with named arguments in the custom attribute. The following example shows this fix.
  • If the aspect can't work without parameters, don't offer it as a live template: remove the SuggestAsLiveTemplate = true setting.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0045.Fixed;
5
6[EditorExperience( SuggestAsLiveTemplate = true )]
7public class LogAttribute : OverrideMethodAspect
8{
9    // Fixed: the category is a property, so the aspect has a parameterless constructor.
10    public string Category { get; set; } = "General";
11
12    public override dynamic? OverrideMethod()
13    {
14        Console.WriteLine( $"[{this.Category}] Executing {meta.Target.Method}." );
15
16        return meta.Proceed();
17    }
18}
19
Source Code
1namespace Doc.LAMA0045.Fixed;
2


3internal class OrderService
4{
5    [Log( Category = "Orders" )]
6    public void PlaceOrder( string customerId ) { }
7}
8
Transformed Code
1using System;
2
3namespace Doc.LAMA0045.Fixed;
4
5internal class OrderService
6{
7    [Log(Category = "Orders")]
8    public void PlaceOrder(string customerId)
9    {
10        Console.WriteLine("[Orders] Executing OrderService.PlaceOrder(string).");
11    }
12}
13

See also