Achieving Event-Driven Messaging in .Net without third party libraries

An Event is basically an action or occurrence that can be identified by a program or list of programs.
Events are usually structured I.e they can carry data from the resulting operation or action but sometimes are used as a notification to trigger other operations.
Aiven.io: Event-driven programming is a paradigm where entities (objects, services, and so on) communicate indirectly by sending messages to one another through an intermediary
Wikipedia: The event-driven messaging is a design pattern, applied within the service-orientation design paradigm to enable the service consumers, which are interested in events that occur within the periphery of a service provider, to get notifications about these events as and when they occur without resorting to the traditional inefficient polling-based mechanism.
Event-driven messaging makes it possible to perform actions or operations whenever the state of an application changes, it reduces close dependence between applications and or services.
Today, we have a number of tools that we can use to achieve event-driven messaging or sourcing, they are sometimes called message brokers, and some of them are Apache Kafka, EventStore ClusterNode, RabbitMq, ActiveMQ, etc.
In recent applications, event-driven messaging is mostly used to trigger subsequent operations from the start or completion of an initiating operation. One might need to send a welcome email to users after signup, get a particular record from the DB after it has been updated, etc.
In our example, we would be using our event messaging system to send a welcome email to newly registered users in our system without awaiting the process or blocking the registration flow.
Pre-requisite knowledge
- Asp.NET Core web API
- C# Events, EventHandler, and delegates
- C# Hosted / Background Service
Create an Asp.Net Web API, I will be using .Net 6,

I will also be mocking both the registration and email sending service, but will outrightly be showing the component of the Event messaging system.
Firstly, let’s create a class to hold our event data, this class is going to inherit from the EventArg class, let us call it “MessageEventArgs”,
This class contains a “MessageType” of type string that will serve as a producer “topic” or in some message brokers “stream name”, it is also going to contain a generic type “Data” to hold any other data that we may want to pass to our consumer or subscriber, you can also make “Data” type of an object. For this example, we make ours an object for simplicity's sake.

Producers: simply source/origin of events
Consumers: listeners/subscribers of these events
Then we can proceed to create a Single instance class that’s going to hold our event handler, a method to call when producing or publishing an event, a static constructor, etc, using Singleton Pattern.
The PublishEvent Method collects the message topic and data to be sent across and builds up an EventArgs to be passed along with the event to the listener.

Going forward we are going to create an Event Hub that’s going to implement the BackgroundService, this service runs in the background in other to listen for events that would be sent throughout the lifetime of our application.
We would also create the event listener method that matches the signature of the handler and assign it.
We then subscribe to our event and listen for any message that would be produced in the “ExecuteAsync” method.
In our event listening method, we would control and operate based on the “MessageTopic” passed through our “EventArg”, we can have multiple topics and their respective actions.

We can then proceed to publish our event after successful registration like below :

And see that our listener picks this event and acts accordingly,

Note: you can also implement your BackgroundService as a queue if you want that.
Don’t forget to register your BackgroundService in the Program or startup class.
You can find the sample project in this repository.
Not “Stranger” Event Driving “Things” eh? :)
Cheers :)
Please Clap *grin*