Skip to content

Repository files navigation

DisposableEvents

Test and Build .NET

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-betaN versions.

Install

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.

Quickstart

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 gone

Filter 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: 9001

Events with no payload need no payload type:

var saved = new DisposableEvent();

saved.Subscribe(() => Console.WriteLine("saved"));
saved.Publish();

Beyond the basics

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

Documentation

Links are absolute so they also work from the rendered README on nuget.org.

License

MIT © Lassi Harjaluoma

About

Disposable events that give an IDisposable subscription in C#

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages