Skip to content

Weakly referenced event subscribers. Keep your .NET events lean and memory-safe.

License

Notifications You must be signed in to change notification settings

ByteAether/WeakEvent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WeakEvent from ByteAether

License NuGet Version NuGet Downloads GitHub Build Status GitHub Security

Weakly referenced event subscribers. Keep your .NET events lean and memory-safe.

Introduction

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.

Features

.NET Standard 2.0

  • 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, or WeakEvent 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.

Installation

Install the latest stable package via NuGet:

dotnet add package ByteAether.WeakEvent

Use the --version option to specify a preview version to install.

Usage

Using the WeakEvent

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 the WeakEvent<TEvent>

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);

API

WeakEvent

  • 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.

WeakEvent<TEvent>

  • 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.

Contributing

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!

License

This project is licensed under the MIT License. See the LICENSE file for details.