티스토리 뷰

반응형

우리는 MVVM을 위해 다음처럼 복잡한 INotifyPropertyChanged 코드를 매번 작성해야 했습니다.

public class UserViewModel : INotifyPropertyChanged
{
    private string _UserName;
    public string UserName { get => _UserName; set => SetProperty(ref _UserName, value); }

    private DateTime? _BirthDate;
    public DateTime? BirthDate { get => _BirthDate; set => SetProperty(ref _BirthDate, value); }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
    public void SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (storage?.Equals(value) == true)
            return;
        storage = value;
        OnPropertyChanged(propertyName);
    }
}

PropertyChanged.Fody 패키지를 사용하면 위의 코드를 아래와 같이 간략하게 작성할 수 있게 됩니다.

public class UserViewModel : INotifyPropertyChanged
{
    public string UserName { get; set; }
    public DateTime? BirthDate { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
}

PropertyChanged.Fody 패키지

PropertyChanged.Fody 패키지는 Code Generator로서, 컴파일이 진행되는 동안 INotifyPropertyChanged 구현 클래스를 찾아 MVVM 코드를 완성시켜줍니다. 다음과 같이 패키지 추가 후 간단히 사용할 수 있습니다.

  1. Visual Studio의 Nuget Package Manager에서 PropertyChanged.Fody 패키지를 설치해주세요.
    Nuget Package Manager
  2. 프로젝트에 FodyWeavers.xml 파일을 추가하고 아래와 같이 작성해주세요.
    <Weavers>
      <PropertyChanged/>
    </Weavers>
    
  3. 이제 INotifyPropertyChanged 클래스를 작성하기만 하면됩니다.
    public class Person : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        
        public string GivenNames { get; set; }
        public string FamilyName { get; set; }
        public string FullName => $"{GivenNames} {FamilyName}";
    }
    
    혹은 [ImplementPropertyChanged] Attribute를 추가하기만 해도 됩니다.
    [ImplementPropertyChanged]
    public class Person
    {
        public string GivenNames { get; set; }
        public string FamilyName { get; set; }
        public string FullName => $"{GivenNames} {FamilyName}";
    }
    
  4. 컴파일이 진행될 때 아래와 같이 구현을 완성시켜줍니다.
    public class Person : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        string givenNames;
        public string GivenNames
        {
            get => givenNames;
            set
            {
                if (value != givenNames)
                {
                    givenNames = value;
                    OnPropertyChanged(InternalEventArgsCache.GivenNames);
                    OnPropertyChanged(InternalEventArgsCache.FullName);
                }
            }
        }
    
        string familyName;
        public string FamilyName
        {
            get => familyName;
            set 
            {
                if (value != familyName)
                {
                    familyName = value;
                    OnPropertyChanged(InternalEventArgsCache.FamilyName);
                    OnPropertyChanged(InternalEventArgsCache.FullName);
                }
            }
        }
    
        public string FullName => $"{GivenNames} {FamilyName}";
    
        protected void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
        {
            PropertyChanged?.Invoke(this, eventArgs);
        }
    }
    
    internal static class InternalEventArgsCache
    {
        internal static PropertyChangedEventArgs FamilyName = new PropertyChangedEventArgs("FamilyName");
        internal static PropertyChangedEventArgs FullName = new PropertyChangedEventArgs("FullName");
        internal static PropertyChangedEventArgs GivenNames = new PropertyChangedEventArgs("GivenNames");
    }
    

Notify를 원하지 않는 Property가 있다면 아래와 같이 Attribute를 추가해주세요.

[DoNotNotify]
public string UserName { get; set; }

같이 Notify 되어야할 Property가 있다면 아래와 같이 작성하실 수 있습니다.

[AlsoNotifyFor("Age")]
public DateTime BirthDate { get; set; }

References

이외에도 다양한 추가기능을 제공합니다. 자세한 사항은 Fody Github 사이트를 참고해주세요.
- https://github.com/Fody/PropertyChanged)

댓글