Skip to content

Latest commit

 

History

History
180 lines (152 loc) · 4.42 KB

README.md

File metadata and controls

180 lines (152 loc) · 4.42 KB

HKW.ReactiveUI

An MVVM library, based on ReactiveUI, using SourceGenerator and Fody for mixed source code generation.

ReactivePropertyAttribute

Adding Notifications to Properties Using Fody and SourceGenerator

partial class MyViewModel : ReactiveObject
{
    [ReactiveProperty]
    public string Name { get; set; } = string.Empty;
}

Generated code

partial class MyViewModel : ReactiveObject
{
    private string $Name;

    [ReactiveProperty]
    public string Name
    {
        get => $Name;
        set => RaiseAndSetName(ref $Name, value, true);
    }

    private void RaiseAndSetName(ref string backingField, string newValue, bool check = true)
    {
        if (!check || !EqualityComparer<string>.Default.Equals(backingField, newValue))
        {
            string oldValue = backingField;
            this.RaisePropertyChanging("Name");
            OnNameChanging(oldValue, newValue);
            backingField = newValue;
            this.RaisePropertyChanged("Name");
            OnNameChanged(oldValue, newValue);
        }
    }
}

ReactiveCommandAttribute

Adding Command Properties to Methods Using the Source Generator

partial class MyViewModel : ReactiveObject
{
    [ReactiveCommand]
    public void Test() { }

    [ReactiveCommand]
    public async Task TestAsync() { }
}

Generated code

partial class MyViewModel : ReactiveObject
{
    private ReactiveCommand<Unit, Unit> _testCommand;
    public ReactiveCommand<Unit, Unit> TestCommand =>
        _testCommand ?? (_testCommand = ReactiveCommand.Create(Test));
    private ReactiveCommand<Unit, Unit> _testAsyncCommand;
    public ReactiveCommand<Unit, Unit> Test1AsyncCommand =>
        _testAsyncCommand ?? (_testAsyncCommand = ReactiveCommand.CreateFromTask(TestAsync));

    [ReactiveCommand]
    public void Test() { }

    [ReactiveCommand]
    public async Task TestAsync() { }
}

NotifyPropertyChangeFromAttribute

Notify property when target property changed
A field is generated to cache the value when EnableCache is true

partial class MyViewModel : ReactiveObject
{
    [NotifyPropertyChangeFrom(nameof(ID), nameof(Name))]
    public bool IsSame => ID == Name;
    protected void InitializeReactiveObject() { }
}

Generated code

partial class MyViewModel : ReactiveObject
{
    private bool _isSame;
    [NotifyPropertyChangeFrom(nameof(ID), nameof(Name))]
    public bool IsSame => _isSame;

    protected void InitializeReactiveObject()
    {
        // InitializeInInitializeObject = true
       _isSame = Name == ID;
    }
    protected void RaiseIsSameChange()
    {
       this.RaiseAndSetIfChanged(ref _isSame, Name == ID, "IsSame");
    }
    private void RaiseAndSetName(ref string backingField, string newValue, bool check = true)
    {
        ...
        this.RaisePropertyChanged("Name");
        RaiseIsSameChange();
    }
    private void RaiseAndSetID(ref string backingField, string newValue, bool check = true)
    {
        ...
        this.RaisePropertyChanged("ID");
        RaiseIsSameChange();
    }
}

When EnableCache is false

partial class MyViewModel : ReactiveObject
{
    [NotifyPropertyChangeFrom(nameof(ID), nameof(Name), EnableCache = false)]
    public bool IsSame => ID == Name;
    protected void InitializeReactiveObject() { }
}

Generated code

partial class MyViewModel : ReactiveObject
{
    private bool _isSame;
    [NotifyPropertyChangeFrom(nameof(ID), nameof(Name), EnableCache = false)]
    public bool IsSame => Name == ID;

    protected void InitializeReactiveObject()
    {
        // InitializeInInitializeObject = true
       _isSame = Name == ID;
    }
    protected void RaiseIsSameChange()
    {
       this.RaiseAndSetIfChanged(ref _isSame, Name == ID, "IsSame");
    }
    private void RaiseAndSetName(ref string backingField, string newValue, bool check = true)
    {
        ...
        this.RaisePropertyChanging("Name");
        this.RaisePropertyChanging("IsSame");
        backingField = newValue;
        this.RaisePropertyChanged("Name");
        this.RaisePropertyChanged("IsSame");
        ...
    }
    private void RaiseAndSetID(ref string backingField, string newValue, bool check = true)
    {
        ...
        this.RaisePropertyChanging("ID");
        this.RaisePropertyChanging("IsSame");
        backingField = newValue;
        this.RaisePropertyChanged("ID");
        this.RaisePropertyChanged("IsSame");
        ...
    }
}