Open sandboxFocusImprove this doc

LAMA5206: A required helper member wasn't found

Severity Error
Reported by Metalama.Patterns.Wpf
Message No <Role> matching <CandidateNames> was found for the <MemberKind> '<Target>'.

Cause

The [Command] and [DependencyProperty] aspects look for helper members by name. With the default naming convention, these members are optional: if no CanSave member or OnFooChanged method exists, the aspect simply works without it.

A helper member becomes required in the following situations, and Metalama reports LAMA5206 on the aspect's target when no member with the expected name exists:

The aspect isn't applied to the target. In the message, <Role> is the role of the missing member, for example property-changed method, <CandidateNames> is the expected name or pattern, <MemberKind> is command or dependency property, and <Target> is the aspect's target. For commands, <Role> always reads can-execute method or can-execute property, even when you set only one of the two attribute properties.

In the following example, the [Command] attribute names a can-execute method CanSaveDocument, but the class has no such method.

1using Metalama.Patterns.Wpf;
2
3namespace Doc.LAMA5206.Error;
4
5public class Document
6{
7    public bool IsModified { get; set; }
8
9    // Error: no method named CanSaveDocument exists.
10    [Command( CanExecuteMethod = "CanSaveDocument" )]
    Error LAMA5206: No can-execute method or can-execute property matching 'CanSaveDocument' was found for the command 'Document.Save()'.

11    private void Save() { }
12
13    private bool CanSave() => this.IsModified;
14}
15

Resolution

  • Check the spelling of the name in the attribute. The names are case-sensitive. Use nameof, for example [Command( CanExecuteProperty = nameof(IsSaveEnabled) )], so that the compiler checks the name.
  • Check that the member has the right kind: CanExecuteMethod only looks for methods, and CanExecuteProperty only looks for properties. The member must be declared in the type of the aspect's target.
  • Add the missing member if it doesn't exist yet.
  • If the member is optional in your design, remove the explicit name from the attribute, or set IsCanExecuteRequired = false in your custom naming convention.

In the following example, the name in the attribute matches the existing CanSave method, and nameof makes the compiler check it.

Source Code
1using Metalama.Patterns.Wpf;
2
3namespace Doc.LAMA5206.Fixed;
4
5public class Document
6{
7    public bool IsModified { get; set; }
8
9    // Fixed: the name matches the can-execute method.
10    [Command( CanExecuteMethod = nameof( CanSave ) )]
11    private void Save() { }
12
13    private bool CanSave() => this.IsModified;
14}
15
Transformed Code
1using Metalama.Patterns.Wpf;
2
3namespace Doc.LAMA5206.Fixed;
4
5public class Document
6{
7    public bool IsModified { get; set; }
8
9    // Fixed: the name matches the can-execute method.
10    [Command(CanExecuteMethod = nameof(CanSave))]
11    private void Save() { }
12
13    private bool CanSave() => this.IsModified;
14
15    public Document()
16    {
17        SaveCommand = DelegateCommandFactory.CreateDelegateCommand(Save, CanSave);
18    }
19
20    public DelegateCommand SaveCommand { get; }
21}
22

See also