Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inheritance support for Command properties #1036

Open
egvijayanand opened this issue Jan 2, 2025 · 1 comment
Open

Inheritance support for Command properties #1036

egvijayanand opened this issue Jan 2, 2025 · 1 comment
Labels
feature request 📬 A request for new changes to improve functionality

Comments

@egvijayanand
Copy link

egvijayanand commented Jan 2, 2025

Overview

A command is a syntactic sugar for methods defined in the ViewModel.

It is made available as a property to enable binding.

As the ViewModel can inherit, so can commands.

This request aims to include the inheritance modifier in the command property, as outlined in the method definition.

Support for the following: abstract, virtual, override, and sealed.

This can be enabled as an explicit opt-in through a RelayCommand attribute property.

API breakdown

  • A Boolean property for the RelayCommand attribute
  • Update Command SG to infer the inheritance modifiers when the attribute above is set to true
// Base class
public virtual IRelayCommand InitializeCommand { get; } // Source generated

// The attribute property name can be formalized
[RelayCommand(Inherit = true)] // Instructing the command property to include the modifier
protected virtual void Initialize() {}

// Derived class
public override IRelayCommand InitializeCommand { get; } // Source generated

[RelayCommand]
protected override void Initialize() {}

Usage example

This ensures that the ViewModel types inherited from BaseViewModel can optionally override the InitializeCommand definition, if necessary.

For example: If logging is to be implemented, the base definition is sufficient for most scenarios. However, for special cases, additional logic will need to be incorporated.

namespace MyApp.ViewModels;

public class BaseViewModel
{
    public virtual IAsyncRelayCommand InitializeCommand { get; }

    public BaseViewModel()
    {
        InitializeCommand = new AsyncRelayCommand(InitializeAsync);
    }

    //[RelayCommand]
    protected virtual Task InitializeAsync()
    {
        // Base command implementation
    }
}

public class ProjectViewModel : BaseViewModel
{
    public override IAsyncRelayCommand InitializeCommand { get; }

    public ProjectViewModel()
    {
        InitializeCommand = new AsyncRelayCommand(InitializeAsync);
    }

    //[RelayCommand]
    protected override Task InitializeAsync()
    {
        // Derived command implementation
        // Can invoke base implementation, if necessary
        // base.InitializeAsync();
    }
}

Breaking change?

No

Alternatives

Manual command infra. Tedious and cumbersome.

Additional context

There is a breaking change in .NET MAUI, Behaviors no longer automatically inherit the BindingContext of their parent.

In one of the projects, EventToCommandBehavior was mapped to invoke a Command on the Page Load event.

As I migrate to the latest version, I will move this Behavior mapping to the base definition for minimal changes, and override the Command in Derived types if additional logic is needed, instead of manually modifying the affected Pages and ViewModels.

Help us help you

No, just wanted to propose this

@egvijayanand egvijayanand added the feature request 📬 A request for new changes to improve functionality label Jan 2, 2025
@egvijayanand
Copy link
Author

egvijayanand commented Jan 2, 2025

If SG can infer the attributes of the initial virtual method definition, the RelayCommand attribute property association can be limited to it, making it even easier.

In simple terms, if a virtual method is annotated with the RelayCommand attribute with the Inherit property set to true, the override methods will inherit the modifier(s) upon further annotation; otherwise, they will not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request 📬 A request for new changes to improve functionality
Projects
None yet
Development

No branches or pull requests

1 participant