특정 특성이 붙어있는 메서드에 대한 기본동작 설정하기

제목이 조금 이상하고 장황하기도 한데요.

현재 제가 DevExpress WPF MVVM 프레임워크를 사용하면서, Command로 지정된 메서드들에게만 Command를 호출하기 전 어떤 동작을 시키고 싶습니다.

가장 무식하고 명시적인 방법은 static 메서드를 하나 만들어서 Command 메서드마다 가장 첫 줄에 static 메서드를 삽입하는 것인데요. 이렇게하지 않고 Attribute나 Source Generator를 이용해서 특정 메서드마다 사전에 어떤 동작을 할 수 있게할 방법이 있을까요?

좋아요 1

Attribute나 소스생성기 방식은 아니고 CompositeCommand를 하나 만드셔서 첫번째 인자에 삽입하고자 하는 Action, 두번째 인자엔 기존 Command를 넣어줘 Action을 실행한 후 Command를 실행하게 하면 되지 않을까요?

좋아요 2

그렇다면 뷰모델에서 단 하나의 커맨드만 바인딩하게 하라는 말씀이신가요?

좋아요 1

아 아뇨. 필요한 만큼 커맨드는 만들되 호출 메서드는 건들지 않고 CompositeCommand라는걸 만들어서 요놈은 기존 커멘드를 호출하거나 Action, Action 인자를 받게 해 사전동작을 구현하는거죠.

좋아요 2

어떤 식인지 상상이 어려운데…번거로우시겠지만 예제를 간단하게 작성해주실 수 있을까요…? ㅠㅠ

좋아요 1

간단하게 작성해봤습니다. 최상위문으로 코딩했어요. 제가 잘못 이해한거라면 부연 설명 바랄께요.


using System;

// 기존 명령어 실행
var command1 = new NormalCommand();
if (command1.CanExecute() == true)
    command1.Execute();

Console.WriteLine();

// 명령실행 전 특정 코드 실행
var command2 = new CompositeCommand(() => Console.WriteLine("으랏차차!"), command1);
if (command2.CanExecute() == true)
    command2.Execute();



/// <summary>
/// 예제를 위한 System.Windows.Input.ICommand 의 단순 버젼
/// </summary>
interface ICommand
{
    bool CanExecute();
    void Execute();
}

class NormalCommand : ICommand
{
    public bool CanExecute() => true;
    public void Execute()
    {
        System.Console.WriteLine("하낫, 둘, 셋, 넷!");
    }
}

class CompositeCommand : ICommand
{
    private Action _beforeAction;
    private ICommand _innerCommand;

    public bool CanExecute() => _innerCommand.CanExecute();

    public void Execute()
    {
        _beforeAction?.Invoke();
        _innerCommand.Execute();
    }

    public CompositeCommand(Action beforeAction, ICommand command) => (_beforeAction, _innerCommand) = (beforeAction, command);
}```
좋아요 3

이방식을 이용하면, AttributeActionCommand (대충 지어봤습니다) 하나 만들어서 Attribute를 읽을 수 있도록 잘 배치해서, beforeAction대신 미리 약속된 액션들을 할 수 있게도 확장할 수 있을 것 같아요.

좋아요 2

그렇다면 뷰모델에서 단 하나의 커맨드만 바인딩하게 하라는 말씀이신가요?

이 말의 아래 의미였습니다.

XAML 쪽에서 바인딩을 할 때 버튼마다 다양한 커맨드를 각각 바인딩하고 있는데, Command 마다 사전 동작을 하기 위해 CompositeCommand를 작성하면 모든 버튼들이 CompositCommand를 바인딩해야하는게 아닌가? 하고 이해했습니다.

소스작성하신 것을 예시로 들면…Normal1Command, Normal2Command, Normal3Command … 등등의 커맨드가 Button1, Button2, Button3에 바인딩 되어 있을 때 위 3개의 커맨드에 대해 어떤 사전 동작을 하는 Command를 쓰고 싶을 경우 기존에 XAML단에서 바인딩 된 것을 모두 CompositeCommand로 바꾸고, 커맨드 파라미터로 이름? 을 넘기는 식으로 해서 메서드를 지정해야한다… 그런 의미실까요?

좋아요 1

흠. 제가 상준님의 정확한 목적을 이해 못한 것 같습니다. ^^; 기존 ICommand 혹은 ICommand 인스턴스가 사용하는 메소드의 소스코드를 건들지 않고라는 이해로 전개한 예제입니다.

좋아요 2

아…ㅠㅠ 그럼 위 방식은 제 의도에서는 못…쓰겠군요ㅠㅠ 감사합니다!

좋아요 1

아무래도 제가 DevExpress WPF MVVM Framework POCO Mode 였다는 걸 질문할 때 처음부터 명시했으면 좋았을 것 같습니다.

해당 내용은 제가 DX MVVM을 쓰는 한, WPF적으로 접근이 아닌 DevExpress 방식으로 접근해야 맞았던 것 같습니다.

이 내용을 DevExpress측에 문의하고 답변을 받았습니다.

좋아요 2