PubSub style events that return an IDisposable subscription. Subscribe, keep the handle, dispose
it to unsubscribe — no -=, no forgotten handler leaks.
Pre-release. The public API may still change between
1.0.0-betaNversions.
dotnet add package DisposableEvents| Package | What it adds |
|---|---|
DisposableEvents |
The library. No dependencies beyond HCommons.*. |
DisposableEvents.R3 |
Expose any event as an R3 Observable<T> |
DisposableEvents.ZLinq |
Zero-allocation ZLinq queries over func results |
Targets net9.0, net8.0, netstandard2.1, and netstandard2.0.
using DisposableEvents;
var clicked = new DisposableEvent<string>();
IDisposable subscription = clicked.Subscribe(name => Console.WriteLine($"clicked: {name}"));
clicked.Publish("save"); // clicked: save
subscription.Dispose();
clicked.Publish("quit"); // nothing — the handler is goneFilter at the subscription, so a handler only sees what it cares about:
var score = new DisposableEvent<int>();
score.Subscribe(n => Console.WriteLine($"high score: {n}"), n => n > 9000);
score.Publish(10); // ignored
score.Publish(9001); // high score: 9001Events with no payload need no payload type:
var saved = new DisposableEvent();
saved.Subscribe(() => Console.WriteLine("saved"));
saved.Publish();A hub, so two components share an event without sharing a reference — the message type is the key:
var hub = new EventHub();
hub.GetSubscriber<PlayerDied>().Subscribe(e => ShowGameOver(e.Cause));
hub.GetPublisher<PlayerDied>().Publish(new PlayerDied("fell in a hole"));Funcs, when you want an answer back rather than fire-and-forget:
var canSave = new DisposableFunc<string, bool>();
canSave.AddHandler(path => path.EndsWith(".json"));
FuncResult<bool> result = canSave.Invoke("world.json");
if (result.TryGetValue(out var allowed) && allowed) { /* ... */ }Event types you can compose into a pipeline — BufferedEvent replays the last message to new
subscribers, FilteredEvent filters once at publish time, FilterAttachingEvent applies default
filters to every subscription, ForwardingEvent fans out to other events.
Await the next message, with cancellation support:
var message = await chat.AwaitNextAsync(cancellationToken);One-shot subscriptions, which unsubscribe themselves after the first message:
ready.SubscribeOnce(() => Start());Links are absolute so they also work from the rendered README on nuget.org.
- Architecture — how the codebase fits together
- Contributing — PRs, labels, building, releases
- Testing — test conventions
- AGENTS.md — guidance for AI coding agents
- Releases — changelog per version
MIT © Lassi Harjaluoma