System.IObservable

Defines a provider for a push-based notification.
link - docs.microsoft.com/en-us/dotnet/api/system.iobservable-1


IObservable<T> - interface represents the class that sends notifications
IObserver<T> - interface represents the class that receives notifications.
Observer - defines a one-to-many dependency between a publisher object and its dependent subscribers.


Observables allow for operations on one thread to be observed on a different thread without too much effort


The IObserver<T> and IObservable<T> interfaces provide a generalized mechanism for push-based notification, also known as the observer design pattern.
Observers register to receive notifications from a TrackLocation object by calling its IObservable<T>.
Subscribe method, which assigns a reference to the observer object to a private generic List<T> object.
The method returns an Unsubscriber object, which is an IDisposable implementation that enables observers to stop receiving notifications.


link - riptutorial.com/design-patterns

public class Stock { 
   private string Symbol {get; set;}
   private decimal Price {get; set;}
}

public class MyObserver : IObserver<Stock>
{
   public IDisposable _unsubscriber;

   public virtual void Subscribe(IObservable<Stock> provider)
   {
      if (provider != null) {
         _unsubscriber = provider.Subscribe(this);
      }
    }

   public virtual void OnCompleted()
   {
      _unsubscriber.Dispose();
   }

   public virtual void OnError(Exception ex)
   {}

   public virtual void OnNext(Stock stock)
   {}
}

public class MyObservable : IObservable<Stock>
{
   private IList<IObserver<Stock> _observers;

   public MyObservable()
   {
      _observers = new List<IObserver<Stock>>();
   }

   public IDisposable Subscribe(IObserver<Stock> observer)
   {
      if (!_observers.Contains(observer))
      {
         _observers.Add(observer);
      }
      return new Unsubscriber(_observers, observer);
   }

   public class Unsubscriber : IDisposable
   {
      private IList<IObserver<Stock>> _observers2;
      private IObserver<Stock> _observer2;
      private bool _disposing = false;

      public Unsubscriber
      {
          IList<IObserver<Stock>> observers,
          IObserver<Stock> observer)
      {
         this._observers2 = observers;
         this._observer2 = observer;
      }

      public void Dispose(){
         Dispose(true);
      }

      protected virtual void Dispose(bool disposing)
      {
         if (_disposing == true)
         {
            return;
         }
         if (disposing == true)
         {
            if (_observer != null && _observers2.Contains(_observer2))
            {
               _observers2.Remove(_observer);
            }
         }
         _disposing = true;
      }
   }

   public void Trade(Stock stock)
   {
      foreach(var observer in _observers)
      {
         if (Stock == null)
         {
            observer.OnError(new ArgumentNullException());
         }
         observer.OnNext(Stock);
      }
   }

   public void End()
   {
      foreach(var observer in _observers.ToArray())
      {
         observer.OnCompleted();
      }
      _observers.Clear();
   }
}

Usage

var provider = new MyObservable(); 
var observer1 = new MyObserver();
observer1.Subscribe(provider);
var observer2 = new MyObserver();
observer2.Subscribe(provider);

provider.Trade(new Stock("MSFT", 50));
provider.Trade(new Stock("APPL", 45));
provider.Trade(null);
provider.End();


© 2022 Better Solutions Limited. All Rights Reserved. © 2022 Better Solutions Limited TopPrevNext