Click here to Skip to main content
13,771,389 members
Click here to Skip to main content
Add your own
alternative version

Stats

14.3K views
8 bookmarked
Posted 12 Mar 2016
Licenced CPOL

Implementing Observer Pattern with Events (C#)

, 12 Mar 2016
Rate this:
Please Sign up or sign in to vote.
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.

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.

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:

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)

Share

About the Author

Lenny Cheng
Canada Canada
I'm a developer from Canada with experience in infrastructure, back-end, and front-end development. 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

You may also be interested in...

Comments and Discussions

 
QuestionObserver pattern need interfaces and subscribe in subject(not observer)? Pin
Damir Galas25-May-18 0:27
memberDamir Galas25-May-18 0:27 
AnswerRe: Observer pattern need interfaces and subscribe in subject(not observer)? Pin
Damir Galas25-May-18 0:42
memberDamir Galas25-May-18 0:42 
QuestionI like it Pin
Kenneth Haugland12-Mar-16 4:25
professionalKenneth Haugland12-Mar-16 4:25 
AnswerRe: I like it Pin
Lenny Cheng12-Mar-16 14:22
memberLenny Cheng12-Mar-16 14: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.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05 | 2.8.181119.1 | Last Updated 13 Mar 2016
Article Copyright 2016 by Lenny Cheng
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid