Getting Issue with Source Cache in ReactiveUI

197 views Asked by At

I have one issue in subscribing to source cache. Let me describe the problem. Lets say I have Test Class

public class Test {
    public bool feature1 {get; set;} = false;
    public bool feature2 {get; set; } = false;
    public string name;
    public Test(string name){
       this.name = name
    }
}

I want to see the changes happening in the property of test class and subscriber react according to change. But with current Implementation getting notification only when source is getting updated with new data not if any property of element in source cache is getting updated.

class Notifier {
    public SourceCache<Test, string> testClassNotifier = new SourceCache<Test, string>(x => x.Name);
    public Notifier(){
        Task.Run(() => 
           {
             this.AddOrUpdateSourceCache();
             this.SubscribeTestObj1();
             this.SubscribeTestObj2();
         }).ConfigureAwait(false);
    }
   
     private AddOrUpdateSourceCache() 
     {
       List<Test> testListObj = new List<Test>() { new Test("test1"), new Test("test2") };
       for (Test obj : testListObj) {
          this.testClassNotifier.AddOrUpdate(obj); 
       }
       Task.Run(async () => {
            for(int i = 0; i<2; i++) {
                this.testListObj[i].feature1 = true;
                await Task.Delay(4000).ConfigureAwait(false);
                // I want here to my get the notification in change with intial values as well.
            }
       }).ConfiguareAwait(false);
     }
     
    private IObservable<Test,string> GetNotification(string name){
        // which api should use here ?? Or any way I can use `WhenAny` here.
        return this.testClassNotifier.Watch(name);
    } 
    private SubscribeTestObj1() {
        this.GetNotification("test1").Subscribe(obj => // do something);
    }

    private SubscribeTestObj1() {
        this.GetNotification("test2").Subscribe(obj => // do something);
    }
}
1

There are 1 answers

4
Magnus On

One solution: implement INotifyPropertyChanged on the Test class, and use AutoRefresh()

Example:

public class Test : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;
    bool _feature1 = false;
    public bool feature1 
    { 
        get => _feature1; 
        set 
        {
            _feature1 = value;
            PropertyChanged?.Invoke(this, new(nameof(feature1)));       
        }
    }
    // ... see the rest of the class in OP's question
}

Test:

var source = new SourceCache<Test, string>(x => x.name);

var a = new Test("a");
var b = new Test("b");

source
    .Connect()
    .AutoRefresh()
    .Watch(b.name)
    .Subscribe(change => Console.WriteLine($"Reason: <{change.Reason}> feature1: <{change.Current.feature1}>"));

source.AddOrUpdate(a);
source.AddOrUpdate(b);
b.feature1 = true;

Output:

Reason: <Add> feature1: <False>
Reason: <Refresh> feature1: <True>