Click here to Skip to main content
15,886,026 members
Articles / Programming Languages / C#

Implementing Observer Pattern with Events (C#)

Rate me:
Please Sign up or sign in to vote.
4.50/5 (5 votes)
12 Mar 2016CPOL2 min read 31.4K   9   4
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)


Written By
Software Developer
Canada Canada
I'm a software developer with experience in infrastructure, back-end, and front-end development. I graduated with a BASc in Computer Engineering from the University of Waterloo in 2019. To learn how my skills may align with your needs, please feel free to send me a message or view my portfolio at: https://lennycheng.com

Comments and Discussions

 
QuestionObserver pattern need interfaces and subscribe in subject(not observer)? Pin
Damir Galas24-May-18 23:27
Damir Galas24-May-18 23:27 
AnswerRe: Observer pattern need interfaces and subscribe in subject(not observer)? Pin
Damir Galas24-May-18 23:42
Damir Galas24-May-18 23:42 
QuestionI like it Pin
Kenneth Haugland12-Mar-16 3:25
mvaKenneth Haugland12-Mar-16 3:25 
AnswerRe: I like it Pin
Lenny Cheng12-Mar-16 13:22
professionalLenny Cheng12-Mar-16 13:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.