티스토리 뷰

반응형

2022.04.14 - [WPF .NET] - Microsoft.Toolkit.Mvvm을 이용한 간단한 프레임워크 part5 - Service 추가(1/2)

2022.03.03 - [WPF .NET] - Microsoft.Toolkit.Mvvm을 이용한 간단한 프레임워크 part4 - LayerPopup 추가

2022.03.02 - [WPF] - Microsoft.Toolkit.Mvvm을 이용한 간단한 프레임워크 part3 - Busy 화면 구현

2022.02.24 - [WPF] - Microsoft.Toolkit.Mvvm을 이용한 간단한 프레임워크 part2 - Frame Navigation

2022.02.21 - [WPF] - Microsoft.Toolkit.Mvvm을 이용한 간단한 프레임워크 part1

4. Customer.cs

모델을 만드는 일반적인 방법은 아래와 같은 클래스를 만들어서 사용하는 것입니다.

단순 조회하는 용도라면 충분히 사용 가능하죠.

    public class Customer
    {
        public string CustomerID { get; set; }
        public string CompanyName { get; set; }
        public string ContactName { get; set; }
        //...
    }

하지만, 데이터를 CRUD하는 화면에서는 아래와 같은 모델이 필요합니다. CustomerID는 Key이기 때문에 수정되지 않아서 그대로 두고, 나머지 프로퍼티들은 PropertyChanged 이벤트를 발생시키도록 만들어야 합니다.

    public class Customer : ObservableObject
    {
        public string CustomerID { get; set; }

        private string _companyName;
        public string CompanyName
        {
            get { return _companyName; }
            set { SetProperty(ref _companyName, value); }
        }

        private string _contactName;
        public string ContactName
        {
            get { return _contactName; }
            set { SetProperty(ref _contactName, value); }
        }
        //...
    }

MVVM Pattern을 사용할 때 제~일 귀찮은 일 중 하나가 PropertyChanged 이벤트를 발생시키도록 SetProperty로 감싸는 작업을 계속 반복하는 것입니다.

개발자도 사람인지라.. 이 부분을 좀 쉽게 코딩하려는 여러가지 방법이 개발되어서 사용 중이고, Microsoft.Toolkit.Mvvm에도 이 부분을 쉽게 처리하기 위한 방법이 존재합니다.

 

우선, ObservableObject, ObservableValidator를 상속받는 partial class를 생성합니다. 그리고, private 필드를 원하는 대로 만든 후 [ObservableProperty]라는 속성을 추가해 줍니다. 

using Microsoft.Toolkit.Mvvm.ComponentModel;

namespace WpfFramework.Models
{
    /// <summary>
    /// Customer 모델
    /// </summary>
    public partial class Customer : ObservableValidator
    {
        public string CustomerID;
        [ObservableProperty]
        private string _companyName;
        [ObservableProperty]
        private string _contactName;
        [ObservableProperty]
        private string _contactTitle;
        [ObservableProperty]
        private string _address;
        [ObservableProperty]
        private string _city;
        [ObservableProperty]
        private string _region;
        [ObservableProperty]
        private string _postalCode;
        [ObservableProperty]
        private string _country;
        [ObservableProperty]
        private string _phone;
        [ObservableProperty]
        private string _fax;
    }
}

빌드를 한번 해주고, Customer에서 F12를 누르면 아래와 같이 2개의 클래스가 존재하는 것을 알 수 있습니다.

두번째 클래스 소스로 이동하면 아래와 같이 자동으로 PropertyChanged 이벤트를 발생시키는 코드가 생성된것을 확인 할 수 있습니다.

    /// <summary>
    /// Customer 모델
    /// </summary>
    public partial class Customer
    {
        [global::System.CodeDom.Compiler.GeneratedCode("Microsoft.Toolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "7.1.0.0")]
        [global::System.Diagnostics.DebuggerNonUserCode]
        [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
        public string CompanyName
        {
            get => _companyName;
            set
            {
                if (!global::System.Collections.Generic.EqualityComparer<string>.Default.Equals(_companyName, value))
                {
                    OnPropertyChanging(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.CompanyNamePropertyChangingEventArgs);
                    _companyName = value;
                    OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.CompanyNamePropertyChangedEventArgs);
                }
            }
        }
        //...
   }

이제~ 아래 이미지 처럼 사용이 가능합니다. 위에서 _contactTitle은 만들었지만, ContactTitle은 만들지 않았지만 사용이 가능해 진것입니다.

이런건 만세 외쳐야 합니다. ㅎㅎ

이 기능 외에도 최소 자리수, 최대 자리수 등등 추가 속성을 이용해서 유효성 검사를 하는 기능도 있는데, 다음 part에서 진행하도록 하겠습니다.

5. 실행 화면

6. 인터페이스를 이용해서 서비스를 개발한 이유

예전에는 서비스를 개발하면, static class에 간단하게 만들거나, 일반 클래스에 static 프로퍼티를 추가해서 만들어 사용했습니다. 그런데, 이렇게 개발하면, 비슷한 서비스를 만들어 사용해야 하거나, 약간의 수정을 해야할 때 수정에 의한 오류가 발생할 수 있고, 유지보수에 불리하게 됩니다.

하지만, 기본 인터페이스를 두고, 상속을 받아서 서비스를 개발하면 여러가지 문제를 쉽게 해결할 수 있습니다. 

만약, 이 프레임워크에서 Sqlite database를 이용하는 서비스를 추가하려면, Microsoft.Data.Sqlite nuget package를 추가하고, SqliteService.cs 클래스를 추가하고 위와 같이 Connection, Command 생성해주고 connectionString만 잘 입력하면 바로 사용이 가능한 서비스가 만들어지며, 기존에 만들었던 IDatabaseService 인터페이스, DatabaseService 클래스는 수정할 필요가 없게 됩니다.

 

인터페이스를 이용했을 때 얻을 수 있는 여러가지 이점 중에 하나만 이야기를 했는데, 앞으로 지속적으로 다른 부분에 대해서도 이야기를 진행하도록 하겠습니다.

7. 소스

kaki104/WpfFramework at part6/add-database-service (github.com)

 

GitHub - kaki104/WpfFramework

Contribute to kaki104/WpfFramework development by creating an account on GitHub.

github.com

 

반응형
댓글