AniMir
AniMir

Reputation: 160

How to link IObservable and IObserver in C#?

I've been studying Observer parttern since this morning, but can't seem to figure out how to implement it with the built-in interfaces. I already looked at some examples but couldn't find any simple example yet.

Here's my code so far, inspired by the Microsoft Documentation :

class ObservableClass : IObservable<bool>, IDisposable
{
    public bool observableBool;
    public List<IObserver<bool>> observers;

    public ObservableClass()
    {
        this.observableBool = false;
        this.observers = new List<IObserver<bool>>();
    }
    public IDisposable Subscribe(IObserver<bool> observer)
    {
        if (!observers.Contains(observer))
        {
            AddObserver(observer);
        }
        return this;
    }
    public void Dispose()
    {
        Console.WriteLine("Disposing...");
    }

    public void AddObserver(IObserver<bool> obs)
    {
        this.observers.Add(obs);
    }

    public void RemoveObserver(IObserver<bool> obs)
    {
        this.observers.Remove(obs);
    }

    public void SwapBool()
    {
        observableBool = !observableBool;
    }

}

the observable class contains an observableBool field. I want to notify the Observer when that field changes value.

Here's my Observer :

class ObserverClass : IObserver<bool>
{
    public IDisposable observable;
    public void OnCompleted()
    {
        Console.WriteLine("Completed");
    }

    public void OnError(Exception error)
    {
        Console.WriteLine("error");
    }

    public void OnNext(bool value)
    {
        Console.WriteLine("Next");
    }
    public virtual void Subscribe(IObservable<bool> obs)
    {
        if (obs != null)
            observable = obs.Subscribe(this);
    }

    public void stopObserve()
    {
        observable.Dispose();
    }
}

And finally my Program :

static void Main(string[] args)
    {
        ObservableClass observable = new ObservableClass();
        ObserverClass observer = new ObserverClass();
        observer.Subscribe(observable);
        Console.WriteLine("subscribed observer");
        observable.SwapBool();
        Console.WriteLine("performed swapBool");
    }

Expected output :

subscribed observer
Completed //Returned by ObserverClass.OnComplete()
performed swapBool

How to make this work ? How to call on OnComplete and the other methods of ObserverClass everytime observableBool changes ?

I know there are other ways to do that, but my goal is to be able to use IObserver and IObservable.

Upvotes: 0

Views: 671

Answers (1)

Theraot
Theraot

Reputation: 40200

You iterate over your set of observables to notify them:

public void SwapBool()
{
    observableBool = !observableBool;
    foreach (observable in observers)
    {
        observable.OnNext(observableBool);
    }
}

You are meant to call OnNext when there is a new value. OnComplete is used to notify that there will be no more values.


I just noticed your observable is IDisposable...

First of all, disposing the result of Subscribe should unsubscribe that observer. Not dispose the observable.

In fact, I would expect that disposing the observable means that it will no longer be sending values (calls OnComplete on everybody and releases the list of observers).

Other concerns include:

  • You probably want a set type so you can add and remove observables more efficiently.
  • List is not thread-safe.
  • Why are you exposing your fields?

Upvotes: 2

Related Questions