How to use IObserver and IObservable Interfaces in C#

No.of Views4401
Bookmarked0 times
Downloads 
Votes0
By  abhi2434   On  15 Dec 2010 09:12:30
Tag : CSharp , CSharp4.0
In this article I will show how to use the IObserver and IObservable Interfaces in C#. These two interfaces is work with connection to Push based approach on Reactive Framework
emailbookmarkadd commentsprint

Images in this article missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at info@codegain.com

 

Introduction

In this article I will show how to use the IObserver and IObservable in C#. These two interfaces is work with connection to Push based approach on Reactive Framework.

IObserver and IObservable as a Dual to Enumerables

First, it should be noted, IObserver and IObservable are actually the mathematical dual of IEnumerable and IEnumerator. Based on iterator pattern, IEnumerable is actually a repository of elements that made up the objects. The IEnumerable holds all the objects and it uses IEnumerator to get each individual objects from the repository. The few methods in IEnumerator which the IEnumerable uses are MoveNext and Current. So for each iteration, the Enumerator calls MoveNext and assigns it to Current which is later on sent back to the external environment.

So if you consider the interface IEnumerable and IEnumerator, it looks like:

public interface IEnumerator<out T> : IDisposable
{
          T Current { get; }
          bool MoveNext();
          void Reset();
}
public interface IEnumerable<out T> : IEnumerable
{
     IEnumerator<T> GetEnumerator();
}

So the IEnumerator has MoveNext which is called every time when we need to yield next element from the store. The MoveNext sets the Current item and sends it back to the Environment. So IEnumerable might be considered as a Pull based approach and it is used for sequential retrieval of objects.

IObservable and IObserver introduced to BCL recently as stated are the mathematical dual of IEnumerable and IEnumerator. Let's see the interfaces a bit:

public interface IObserver<in T>
{
    void OnCompleted();
    void OnError(Exception error);
    void OnNext(T value);
}

and for IObservable, it is:

public interface IObservable<out T>
{
      IDisposable Subscribe(IObserver<T> observer);
}

 

Image Loading

Hence, if you see the difference between the two Interfaces, IEnumerator has Current and MoveNext. These methods are used to Pull objects from the repository. IObserver has OnNext which is used to Push objects to the repository. Again, if you look into IEnumerable, it uses GetEnumerator to pull back the object of IEnumerable, while IObservable has a Subscribe method which is used to push an Observer to the Observable. Hence you can easily say, Observable interfaces in BCL are a dual to Enumerables where the former uses Push based approach and the later uses pull based approach.

Where Are They Useful?

If you recollect the Observer design pattern, you should know it already. Observer pattern actually holds a list of dependent objects known as Observer and notifies when certain state of the Observer changes. We have already got an idea of ObservableCollection which notifies the change to the collection to the external environment. IObserver and IObservable gives you a chance to enhance this flexibility more. Let's see a few lines of code:

public class CustomObserver
{

    private ObservableCollection<int> myrepository;

    public ObservableCollection<int> MyRepository
    {
        get
        {
            this.myrepository = this.myrepository ?? new ObservableCollection<int>();
            return this.myrepository;
        }
    }

    public void LoadRepository(int item)
    {
        this.MyRepository.Add(item);
    }

    private List<int> filteredcollection;
    public List<int> FilteredCollection
    {
        get
        {
            this.filteredcollection = this.filteredcollection ?? new List<int>();
            return filteredcollection;
        }
    }
    public IDisposable GetObserved()
    {

        IObservable<IEvent<NotifyCollectionChangedEventArgs>> numberObserver = 
	Observable.FromEvent<NotifyCollectionChangedEventArgs>
	(this.MyRepository, "CollectionChanged");
        Action<IEvent<NotifyCollectionChangedEventArgs>> subscriptionAction = item =>
        {
            switch (item.EventArgs.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    var newValues = item.EventArgs.NewItems.Cast<int>().Where
							(n => n % 2 == 0);
                    this.FilteredCollection.AddRange(newValues);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    foreach (int n in item.EventArgs.OldItems)
                        this.FilteredCollection.Remove(n);
                    break;
                case NotifyCollectionChangedAction.Replace:
                    foreach (int n in item.EventArgs.OldItems)
                        this.FilteredCollection.Remove(n);
                    goto case NotifyCollectionChangedAction.Add;
            }
        };

        return numberObserver.Subscribe(subscriptionAction);
    }
}

So in this class, I have implemented a simple collection of objects and registered the PropertyChanged event of ObservableCollection. Hence the Action method SubscriptionAction will be called automatically and reevaluate the list FilteredCollection whenever the Observer MyRepository gets an object.

So to demonstrate, let's look at the Main method:

static void Main(string[] args)
{

    CustomObserver myobj = new CustomObserver();
    IDisposable unregisterobj = myobj.GetObserved();

    bool DoContinue = false;
    do
    {
        try
        {
            Console.Write("Enter a Value:");
            int item = Convert.ToInt32(Console.ReadLine());

            myobj.LoadRepository(item);

            Console.WriteLine("Filtered List counter : {0}", 
				myobj.FilteredCollection.Count);

            Console.WriteLine("Do you want to continue?[1/0]");
            DoContinue = Convert.ToInt32(Console.ReadLine()) == 1;
        }
        catch { continue; }
    } 
    while (DoContinue);

    Console.WriteLine("Disposing Registration...");
    unregisterobj.Dispose();

    Console.ReadKey();
}

Being so straightforward, we create an object of out class CustomObserver and called the method GetObserved which in turn calls Subscribe method from the Observer and returns the Disposable object. You must remember the Subscribe method returns a IDisposable which will be used to unsubscribe the method by just calling the Dispose method of it.

Image Loading

 Just as you might expect, if you run the application, the application allows you to enter numeric values each of which is observed and added to the FilteredCollection. Hence when you enter Even values, the FilteredCollection gets updated.

The FromEvent is a method from Reactive framework that generates an Observable from an event. In the call, the Observer will observe the collection for the event CollectionChanged. We will discuss more about the Reactive framework later.

Download Sample Project

Download source files -28 kb

Conclusion

I hope you like my demonstration. Feel free to write your comments and feedback. Thank you for reading.

 
Sign Up to vote for this article
 
About Author
 
abhi2434
Occupation-Not Provided
Company-Not Provided
Member Type-Senior
Location-Not Provided
Joined date-22 Oct 2009
Home Page-Not Provided
Blog Page-Not Provided
 
 
Other popularSectionarticles
    Since we have multicore processors are now so we can take advantages of multicore processor with parallel execution in C# 4.0. There are some time consuming task for the computer for example a long for loop or similar kind of things. This kind of task can be done parallel with parallel class in C# 4.0.
    Published Date : 12/Jul/2011
    In this article, i will explain how to use the How to use ExpandoObject Class in .NET 4.0.The ExpandoObject class is introduced on .NET Framework 4.0 and inherited using many interfaces.
    Published Date : 16/Apr/2011
    C# 4.0 supports Dynamic Programming by introducing new Dynamic Typed Objects
    Published Date : 26/May/2010
    Dynamic Datatype in C# 4.0 is quit bit familiar to Var Datatype. Deference between Var and Dynamic is VAR initialized on CompileTime and Dynamic initialized On Runtime
    Published Date : 17/May/2010
    Through this article, i will introduce in FCL named Tuple which can store n - number of values in it. Yes, you specify the type of each of those variables as generic parameters, and the object will create those values for you
    Published Date : 15/Nov/2010
Comments
There is no comments for this articles.
Leave a Reply
Title:
Display Name:
Email:
(not display in page for the security purphase)
Website:
Message:
Please refresh your screen using Ctrl+F5
If you can't read this number refresh your screen
Please input the anti-spam code that you can read in the image.
^ Scroll to Top