Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Implementing Observer Pattern with Events (C#)

4.50/5 (5 votes)
12 Mar 2016CPOL2 min read 32.5K  
This article provides a basic template for implementing the Observer Pattern using an event.

Introduction

This article provides a basic template for implementing the Observer Pattern using an event. This article aims to concisely share with you how to use events to implement the Observer Pattern by presenting the bare minimum code needed to do so. Please feel free to modify this template to suit your projects’ requirements.

To enhance your learning experience, you can download a Console project and experiment with it as you read this article from here.

Background

The Observer Pattern is frequently implemented in one of two ways:

  1. We make our own Subject/Observer abstractions and implementations (e.g., creating, ISubject, IObservable, and relevant derived classes)
  2. We let our Subject/Observer inherit from IObservable<T> and IObserver<T>

Although these are the most popular implementations, we may also consider another implementation: using events.

Using the Code

There are two essential classes: the Subject class and Observer class.

Subject

The subject contains the event field and can raise the event.

C#
public class Subject
   {
       public event EventHandler eventHandler; //We can also consider
               //using an auto-implemented property instead of a public field

       public void NotifyObservers()
       {
           if (eventHandler != null)   //Ensures that if there are no handlers,
                           //the event won't be raised
           {
               eventHandler(this, EventArgs.Empty);    //We can also replace
                               //EventArgs.Empty with our own message
           }
       }
   }
Notes
  • Contains the event: public event EventHandler eventHandler; This is the glue that holds the subject and the observers together
  • Raises the event: eventHandler(this, EventArgs.Empty); All observers subscribed to this event will then be notified that this event has been raised

Observer

The observer can subscribe and unsubscribe to the subject. It also attaches a handler to the subject's event.

C#
public class Observer
  {
      Subject subject;

      public Observer(Subject subject)
      {
          this.subject = subject;
      }

      public void Subscribe()
      {
          subject.eventHandler += DoSomething;    //Every time the event is raised
                      //(from eventHandler(this,EventArgs.Empty);), DoSomething(...) is called
      }

      public void UnSubscribe()
      {
          subject.eventHandler -= DoSomething;    //Now, when the event is raised,
                          //DoSomething(...) is no longer called
      }

      private void DoSomething(object sender, EventArgs e)
      {
          Console.WriteLine("This Observer instance has received
              a notification from its associated Subject.");
      }
  }
Notes
  • Contains the event handler: private void DoSomething(object sender, EventArgs e) {...} This is called when Subject's eventHandler is raised.
  • Subscribes by attaching a handler to Subject's eventHandler: subject.eventHandler += DoSomething; We can also subscribe multiple times.
  • Unsubscribes by detaching the handler from subject's eventHandler: subject.eventHandler -= DoSomething;

Main

We run our Observer Pattern in the Main method:

C#
class Program
    {
        static void Main(string[] args)
        {
            Subject subject = new Subject();
            Observer observer1 = new Observer(subject);
            Observer observer2 = new Observer(subject);

            //subscribe the Observer instances to "subject"
            observer1.Subscribe();
            observer2.Subscribe();

            subject.NotifyObservers();  //both Observer instances' 
            			//DoSomething(object sender, EventArgs e) method are called

            observer1.UnSubscribe();
            subject.NotifyObservers();  //only observer2's  DoSomething(object sender, EventArgs e) 
            			//method is called because observer2 has unsubscribed from "subject"

            Console.ReadKey();
        }
    }
Notes
  • Since we have unsubscribed observer1, our console outputs the statement "This Observer instance has received a notification from its associated Subject." three times instead of four times.

Further Reading

Thanks for reading! Hopefully, this article helped you learn another way of implementing the Observer Pattern in C#. If you have any comments, please feel free to share it below.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)