Mastering Subscribe and Unsubscribe Events in .NET Core
A Practical Guide for Clean Event-Driven Code
Have you ever wondered how events work under the hood in .NET Core? Maybe you’ve worked with delegates and handlers before, but you’re still unsure about how subscribing and unsubscribing from events works. Events are an essential part of building flexible and interactive applications, especially in event-driven architectures.
In this blog, we’re going to dive deep into subscribing and unsubscribing events in .NET Core, explore how to manage them effectively, and ensure we clean up resources properly by avoiding common pitfalls like memory leaks. Plus, I’ll throw in a practical code example so you can see it in action!
📌Explore more at: https://dotnet-fullstack-dev.blogspot.com/
🌟 Restack would be appreciated! 🚀
What Are Events in .NET Core?
In .NET Core, an event is a way for a class to provide notifications when something important happens. Events rely on delegates to define the type of event handlers that can subscribe to it. It allows multiple objects to be notified and react to an event being raised.
Here’s a quick analogy: think of events as a notification system. When something interesting happens (like a button being clicked), anyone who’s “subscribed” to that event gets notified and can respond accordingly.
Subscribing to Events
Subscribing to an event means attaching an event handler (a method that handles the event) to the event. Every time the event is raised, all the subscribed handlers are called.
Example: Subscribing to an Event
Let's create a simple Item
class that raises an event when an item is added:
public class Item
{
public delegate void ItemAddedEventHandler(object source, EventArgs args);
public event ItemAddedEventHandler ItemAdded;
public void AddItem()
{
Console.WriteLine("Item is added.");
OnItemAdded();
}
protected virtual void OnItemAdded()
{
if (ItemAdded != null)
{
ItemAdded(this, EventArgs.Empty);
}
}
}
Now, we can create a service that subscribes to this event:
public class NotificationService
{
public void OnItemAdded(object source, EventArgs args)
{
Console.WriteLine("NotificationService: Item has been added, notifying subscribers...");
}
}
public class Program
{
static void Main(string[] args)
{
var item = new Item();
var notificationService = new NotificationService();
// Subscribing to the event
item.ItemAdded += notificationService.OnItemAdded;
item.AddItem(); // Raises the event
}
}
In this example, the NotificationService
subscribes to the ItemAdded
event. When AddItem()
is called, the event is triggered, and the OnItemAdded
method in NotificationService
is executed.
Unsubscribing from Events
Unsubscribing from events is equally important as subscribing. If you don’t unsubscribe from events when you’re done with them, you might end up with memory leaks because the event handlers will keep references to the subscribers, preventing them from being garbage collected.
Unsubscribing Example
To unsubscribe from an event, you simply use the -=
operator:
item.ItemAdded -= notificationService.OnItemAdded;
If you unsubscribe before the event is raised, the event handler will not be called.
Let’s add this to the example:
public class Program
{
static void Main(string[] args)
{
var item = new Item();
var notificationService = new NotificationService();
// Subscribing to the event
item.ItemAdded += notificationService.OnItemAdded;
item.AddItem(); // Raises the event
// Unsubscribing from the event
item.ItemAdded -= notificationService.OnItemAdded;
item.AddItem(); // Event is raised again, but no handler is executed
}
}
In this case, after the first AddItem()
call, the NotificationService
is unsubscribed from the ItemAdded
event. Therefore, when AddItem()
is called again, the event is raised, but no one is there to handle it.
Real-World Use Case: Event-Driven Architectures
In larger applications, events are often used to create loosely coupled components that can communicate with each other without needing to know the internal workings of the other components. Event-driven systems are especially useful in scenarios like:
Microservices architectures, where services can publish events, and other services can subscribe to them.
UI applications, where user interactions (like clicking buttons or submitting forms) trigger events.
Message-based systems, where a queue or message bus can raise events for different consumers to handle.
Common Pitfalls to Avoid
Forgetting to Unsubscribe: Always remember to unsubscribe from events when the subscriber is no longer needed to avoid memory leaks.
Multiple Subscriptions: Be cautious when subscribing to an event multiple times accidentally, as this will cause the event handler to be executed multiple times.
Handling Exceptions: Make sure to handle exceptions within event handlers properly. If an exception occurs, it could prevent other subscribers from receiving the event.
Conclusion: Mastering Events
Working with events, subscribing, and unsubscribing in .NET Core is not just about writing functional code—it’s about building clean, maintainable, and efficient solutions. Properly handling subscriptions and unsubscriptions ensures that your application remains responsive and free from memory leaks.
Events provide a powerful way to build decoupled systems, and with great power comes great responsibility. So, the next time you work with events in your code, remember to subscribe smartly and unsubscribe diligently!