.NET MAUI - MVVM and CommunityToolkit.Mvvm

2022. 8. 9. 00:00MAUI

반응형

MVVM(Model-View-ViewModel)은 UI와 비 UI 코드를 분리하기 위한 UI 아키텍처 디자인 패턴입니다. MVVM을 사용하면 XAML에서 선언적으로 UI를 정의하고 데이터 바인딩 마크업을 사용하여 데이터 및 명령이 포함된 다른 계층에 연결합니다. 데이터 바인딩 인프라는 UI와 연결된 데이터를 동기화된 상태로 유지하고 사용자 입력을 적절한 명령으로 라우팅하는 느슨한 결합을 제공합니다.

느슨한 결합을 제공하기 때문에 데이터 바인딩을 사용하면 서로 다른 종류의 코드 간의 엄격한 종속성이 줄어듭니다. 이렇게 하면 다른 코드 단위 에서 의도하지 않은 부작용을 일으키지 않고 개별 코드 단위(메서드, 클래스, 컨트롤 등)를 더 쉽게 변경할 수 있습니다. 이러한 분리는 많은 디자인 패턴에서 중요한 개념인 관심사 분리의 예입니다.

 

코드를 분리하면 다음과 같은 많은 이점이 있습니다.

  • 반복적이고 탐색적인 코딩 스타일을 가능하게 합니다. 격리된 변경은 덜 위험하고 실험하기 쉽습니다.
  • 단위 테스트를 단순화합니다. 서로 격리된 코드 단위는 프로덕션 환경 외부에서 개별적으로 테스트할 수 있습니다.
  • 팀 협업을 지원합니다. 잘 설계된 인터페이스를 준수하는 분리된 코드는 개별 개인 또는 팀에서 개발하고 나중에 통합할 수 있습니다.
  • 유지보수성 향상. 분리된 코드에서 버그를 수정하면 다른 코드에서 재발할 가능성이 줄어듭니다.

MVVM과 달리 보다 일반적인 "코드 숨김" 구조의 앱은 일반적으로 표시 전용 데이터에 데이터 바인딩을 사용하고 컨트롤에 의해 노출된 이벤트를 직접 처리하여 사용자 입력에 응답합니다. 이벤트 처리기는 코드 숨김 파일(예: MainPage.xaml.cs)에서 구현되며 일반적으로 UI를 직접 조작하는 코드를 포함하는 컨트롤과 밀접하게 연결됩니다. 이로 인해 이벤트 처리 코드를 업데이트하지 않고 컨트롤을 교체하는 것이 어렵거나 불가능합니다. 이 아키텍처를 사용하면 코드 숨김 파일에 데이터베이스 액세스 코드와 같이 UI와 직접 관련이 없는 코드가 누적되어 결국 다른 페이지에서 사용하기 위해 복제되고 수정됩니다.

 

커뮤니티 툴깃 MVVM

CommunityToolkit.Mvvm을 검색하고 최신 버전을 설치합니다. 

Source Generator (소스 생성기)

버전 8.0부터 MVVM 도구 키트에는 MVVM 아키텍처를 사용하여 코드를 작성할 때 상용구를 크게 줄이는 데 도움이 되는 새로운 Roslyn 원본 생성기가 포함되어 있습니다. 

즉, 코드를 작성할 때 MVVM 도구 키트 생성기가 백그라운드에서 추가 코드를 생성하는 작업을 처리하므로 걱정할 필요가 없습니다. 그러면 이 코드가 컴파일되어 애플리케이션에 포함되므로 최종 결과는 모든 추가 코드를 수동으로 작성한 것과 똑같지만 모든 추가 작업을 수행할 필요가 없습니다.

 

MVVM 에서 View model 에서 Name 속성에 대한 Notify 처리를 위해 다음과 같이 코딩한다. 

public class SourceGeneratorViewModel : ObservableObject
{
    private string _name;
    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }
}

하지만 source generator 는 attribute 를 통해 다음과 같이 처리 할 수 있다.

[ObservableProperty]
private string? name;

Command 같은 경우도 가능 하다.

온전한 코드는 다음과 같다. 

private void ChangeName() => Name = "Change New Name";
private IRelayCommand changeNameCommand;
public IRelayCommand ChangeNameCommand =>
    changeNameCommand ??= new RelayCommand(ChangeName);

source generator 를 사용하면 다음과 같다.

[RelayCommand]
private void ChangeName() => Name = "Change New Name";

 

Test 용 Xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp1.MVVM.SourceGenerator"
             xmlns:local="clr-namespace:MauiApp1.MVVM"
             Title="SourceGenerator">
    <ContentPage.BindingContext>
        <local:SourceGeneratorViewModel />
    </ContentPage.BindingContext>
    <VerticalStackLayout Padding="10" Spacing="20">
        <Label 
            Text="{Binding Name}" 
            VerticalOptions="Center"
            HorizontalOptions="Center"
            FontSize="24"/>

        <Button Command="{Binding ChangeNameCommand}" Text="Change Name" />
    </VerticalStackLayout>
</ContentPage>

ViewModel

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace MauiApp1.MVVM;
public partial class SourceGeneratorViewModel : ObservableObject
{
    public SourceGeneratorViewModel()
    {
        Name = "My Name is Yogingang";
    }

    //private string _name;
    //public string Name
    //{
    //    get => _name;
    //    set => SetProperty(ref _name, value);
    //}

    [ObservableProperty]
    private string name;


    //private void ChangeName() => Name = "Change New Name";
    //private IRelayCommand changeNameCommand;
    //public IRelayCommand ChangeNameCommand =>
    //    changeNameCommand ??= new RelayCommand(ChangeName);

    [RelayCommand]
    private void ChangeName() => Name = "Change New Name";

}

Button 클릭 전
Button 클릭 후

관련영상

https://youtu.be/tpHdXHySpTQ

 

 

반응형

'MAUI' 카테고리의 다른 글

.NET MAUI - MVVM ObservableRecipient  (0) 2022.08.11
.NET MAUI - MVVM ObservableObject  (0) 2022.08.10
.NET MAUI - Behaviors  (0) 2022.08.08
.NET MAUI - Triggers (2)  (0) 2022.08.05
.NET MAUI - Triggers (1)  (0) 2022.08.04