Publish-Subscribe or Pub-Sub is a design pattern that allows loose coupling between the application components.
Here senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers. Messages are published without the knowledge of what or if any subscriber of that knowledge exists. Delegate form the basis of this design pattern in C#.
There is also another design pattern which is much similar to pub-sub that is the Observer pattern.
However,
The major difference in Pub-Sub design is the event channel that publisher generates to notify changes to its subscriber without any knowledge of subscriber existence.
Delegates, EventHandlers and Event keyword plays a special role in this event handling mechanism. Let’s see how they are used in Pub-Sub.
First, let’s see the implementation of Pub-Sub pattern in C# using Action delegate defined in .NET Framework.
An Action delegate is nothing but a built-in delegate with return type as void.
In above code, we created a publisher and subscribe to its events using two anonymous methods sharing the signature of Action delegate.
We able to use += on the OnChange property because of the multicast feature provided by delegates.
Note: You can learn more about multicast feature in delegates in my blog post Multicast Delegates In C#.
Although the programs look good there is some weakness in the program.
If you use = instead of += you will effectively remove the first subscriber from the OnChange property.
Also,
As OnChange is a public property any outside user of the class can raise the event by just calling p.OnChange().
Pub-Sub Using Event Keyword
Let’s see the same code using event keyword,
As you can see in above code, with the use of event keyword we are using OnChange as a field instead of property. I know its still public.
But,
By using event keyword compiler protects our field from unwanted access.
And,
It does not permit the use of = (direct assignment of a delegate). Hence, your code is now safe from the risk of removing previous subscribers by using = instead of +=.
Also, you may have noticed special syntax of initializing the OnChange field to an empty delegate like this delegate { }. This ensures that our OnChange field will never be null. Hence, we can remove the null check before raising the event, if no other members of the class making it null.
Pub-Sub Using EventHandlers
In Pub-Sub, the publisher and subscriber don’t know about the existence of one another. There is a third component, called broker or message broker or event bus, which is known by both the publisher and subscriber, which filters all incoming messages and distributes them accordingly.
Here EventHandler is our that third component that acts as event bus between publisher and subscriber.
So instead of using Action delegate, we have to use EventHandler which is defined as the following delegate:
By default, EventHandler takes sender object and some event argument as a parameter. Here sender is the same object which raises the event, which is publisher in our case.
Let’s see an example
Here the pub class uses generic EventHandler, which specifies the type of event argument you need to pass to the while raising the EventHandler OnChange, MyArgs in our case
Exception Aware Event Raise
Let’s start with code this time
When you run this code you will find that the first subscriber is executed successfully and the second one throws an exception and the third one is never called.
If this not the behavior you want, you need to manually raise the event and handle the exception. This can be achieved by using the GetInvoctionList method defined in Delegate base class.
Let’s see the code example
Where To Apply Publish Subscribe Pattern?
When you want loose coupling between objects that interact with each other.
When you want to specify the kind of notification you want to send, by defining a number of events, to a subscriber depending on the type or scope of change. The subscriber will thus be able to choose to subscribe a specific notifications that matters.
Note: You can download the complete solution demo from my github repository.
Further Reading
Observer Pattern C# - The observer design pattern enables a subscriber to register with and receive notifications from a provider. It is suitable for any scenario that requires push-based notification. The pattern defines a provider (also known as a subject or an observable) and zero, one, or more observers.
Observer vs Pub-Sub pattern by Ahmed Shamim Hassan - Despite the differences between these patterns, some might say that Publisher-Subscriber pattern is a variation of Observer pattern because of the conceptual similarity between them. However, Ahmed Shamim explains how they are different from each other in a very illustrative way!
Subscribe to Code with Shadman
Get the latest posts delivered right to your inbox