Weakly referenced event subscribers. Keep your .NET events lean and memory-safe.
The weak event pattern is a proven approach to managing event subscriptions in .NET, as detailed in Microsoft's documentation on WPF weak event patterns. This design avoids memory leaks by holding event subscribers with weak references, which means that even if an object remains subscribed to an event, it can still be garbage collected when no longer in use.
Leveraging the power of .NET's weak reference mechanism, as explained in the .NET garbage collection documentation, the WeakEvent library ensures that event subscribers do not prevent the garbage collector from reclaiming memory. This decoupling of publishers and subscribers provides a robust solution for managing event lifecycles without the need for manual unsubscription.
In the context of Blazor components, this functionality is particularly valuable. When using Blazor, developers often face challenges with unsubscribing from events during component disposal. With WeakEvent, you can safely subscribe to events in your Blazor components without worrying about leftover subscriptions that could block garbage collection. This ensures that unloaded components are properly cleaned up, preventing the accumulation of dead components in memory and avoiding potential memory leaks.
- Weak References: Subscribers are held via weak references, allowing the garbage collector to reclaim them when they are no longer needed.
- Events With or Without Data: Use
WeakEvent<TEvent>
when you need to pass event data to subscribers, orWeakEvent
for simple notifications that don't require additional information. - Automatic Cleanup: Dead subscribers (whose targets have been garbage-collected) are automatically removed when the event is raised.
- Simple API: Intuitive methods for subscribing, unsubscribing, and publishing events.
Install the latest stable package via NuGet:
dotnet add package ByteAether.WeakEvent
Use the --version
option to specify a preview version to install.
using ByteAether.WeakEvent;
// Create an instance of the weak event without event data
var myEvent = new WeakEvent();
// Create a subscriber and subscribe
var subscriber = () => Console.WriteLine("Event received!");
myEvent.Subscribe(subscriber);
// Raise the event
await myEvent.PublishAsync();
using ByteAether.WeakEvent;
// Create an instance of the weak event with event data
var myEvent = new WeakEvent<MyEventData>();
// Create a subscriber and subscribe
var subscriber = (MyEventData data) => Console.WriteLine("Received: " + data.Message);
myEvent.Subscribe(subscriber);
// Raise the event
await myEvent.PublishAsync(new MyEventData("Hello, World!"));
// Define your event data
public record MyEventData(string Message);
Subscribe(Action handler)
Subscribe(Func<Task> handler)
Subscribe(Func<CancellationToken, Task> handler)
Subscribes the specified handler to the event. The handler will be invoked when the event is raised, provided that its target is still alive.Unsubscribe(Action handler)
Unsubscribe(Func<Task> handler)
Unsubscribe(Func<CancellationToken, Task> handler)
Unsubscribes the specified handler from the event.PublishAsync(CancellationToken cancellationToken = default)
Raises the event by invoking all live subscribers. Dead subscribers (whose targets have been garbage-collected) are removed.
Subscribe(Action<TEvent> handler)
Subscribe(Func<TEvent, Task> handler)
Subscribe(Func<TEvent, CancellationToken, Task> handler)
Subscribes the specified handler to the event. The handler will be invoked when the event is raised, provided that its target is still alive.Unsubscribe(Action<TEvent> handler)
Unsubscribe(Func<TEvent, Task> handler)
Unsubscribe(Func<TEvent, CancellationToken, Task> handler)
Unsubscribes the specified handler from the event.PublishAsync(TEvent eventData, CancellationToken cancellationToken = default)
Raises the event by invoking all live subscribers with the provided event data. Dead subscribers (whose targets have been garbage-collected) are removed.
We welcome all contributions! You can:
- Open a Pull Request: Fork the repository, create a branch, make your changes, and submit a pull request to the
main
branch. - Report Issues: Found a bug or have a suggestion? Open an issue with details.
Thank you for helping improve the project!
This project is licensed under the MIT License. See the LICENSE file for details.