LiteObservableEvents 1.0.0
dotnet add package LiteObservableEvents --version 1.0.0
NuGet\Install-Package LiteObservableEvents -Version 1.0.0
<PackageReference Include="LiteObservableEvents" Version="1.0.0" />
<PackageVersion Include="LiteObservableEvents" Version="1.0.0" />
<PackageReference Include="LiteObservableEvents" />
paket add LiteObservableEvents --version 1.0.0
#r "nuget: LiteObservableEvents, 1.0.0"
#:package LiteObservableEvents@1.0.0
#addin nuget:?package=LiteObservableEvents&version=1.0.0
#tool nuget:?package=LiteObservableEvents&version=1.0.0
LiteObservableEvents
Lightweight observable event hub and source-generated event bridges for .NET, with optional weak-reference (holder) lifecycle and MVVM-style interactions.
Features
- Event hubs:
StrongReferenceEventHubandWeakReferenceEventHubfor central subscription management. - Holder-based lifecycle: Subscribe with a holder object; when the holder is GC'd, subscriptions are cleaned up automatically (WeakReferenceMessenger-style).
- Source-generated
Events(): Generate type-safe, observable wrappers for instance/static events via source generator. - Interactions:
LiteObservableEvents.Interactionsfor ViewModel–View communication (e.g. confirmation dialogs).
Demos (WpfApp)
The WpfApp project is a small WPF demo that shows the following.
1. WeakReferenceEventHub + holder
Subscriptions use holder: this (the window). On window close, all subscriptions for that holder are disposed. Cleanup() or new subscriptions remove dead holder subscriptions.
this.Events().Closed
.Subscribe(_ =>
{
_confirmInteractionRegistration?.Dispose();
WeakReferenceEventHub.Default.UnsubscribeAll(this);
ViewModel?.Dispose();
});
2. Static event subscription
Hand-written add/remove:
WeakReferenceEventHub.Default.Subscribe<bool, bool>(
holder: this,
addHandler: h => MyStaticObject.MyStaticEvent += h,
removeHandler: h => MyStaticObject.MyStaticEvent -= h,
onNext: _ => Debug.WriteLine("Raised - MyStaticObject.MyStaticEvent += h"));
Reflection:
WeakReferenceEventHub.Default.Subscribe<bool>(
holder: this,
target: typeof(MyStaticObject),
eventName: nameof(MyStaticObject.MyStaticEvent),
onNext: _ => Debug.WriteLine("Raised - MyStaticObject.MyStaticEvent reflection"));
3. Static object's event (singleton)
Source-generated Events():
WeakReferenceEventHub.Default.Subscribe(this, MySingletonObject.Instance.Events().MyEvent, _ =>
{
Debug.WriteLine("Raised - MySingletonObject.Instance.Events().MyEvent source-generated");
});
Hand-written add/remove:
WeakReferenceEventHub.Default.Subscribe<bool, bool>(
holder: this,
addHandler: h => MySingletonObject.Instance.MyEvent += h,
removeHandler: h => MySingletonObject.Instance.MyEvent -= h,
onNext: _ => Debug.WriteLine("Raised - MySingletonObject.Instance.MyEvent += h"));
Reflection:
WeakReferenceEventHub.Default.Subscribe<bool>(
holder: this,
target: MySingletonObject.Instance,
eventName: nameof(MySingletonObject.MyEvent),
onNext: _ => Debug.WriteLine("Raised - MySingletonObject.Instance.MyEvent reflection"));
4. Interactions (ViewModel ↔ View)
ViewModel exposes an Interaction<string, bool>. View registers a handler (e.g. MessageBox); a command calls Handle(...).ToTask() and shows the result.
View — register handler:
_confirmInteractionRegistration = ViewModel.ConfirmAction.RegisterHandler(context =>
{
var result = MessageBox.Show(context.Input, "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question);
context.SetOutput(result == MessageBoxResult.Yes);
});
ViewModel — declare and invoke:
public Interaction<string, bool> ConfirmAction { get; } = new();
[RelayCommand]
private async Task AskConfirmAsync()
{
var approved = await ConfirmAction.Handle("Do you want to continue?").ToTask();
LastResult = approved ? "User chose: Yes" : "User chose: No";
}
5. Raising events from ViewModel
A command toggles a bool and raises both static and singleton events; the UI binds to the toggle value.
[ObservableProperty]
private bool _staticEventToggle;
[RelayCommand]
private void RaiseStaticEvents()
{
StaticEventToggle = !StaticEventToggle;
MyStaticObject.RaiseSomeEvent(StaticEventToggle);
MySingletonObject.Instance.RaiseSomeEvent(StaticEventToggle);
}
Run WpfApp and use the two buttons to try the confirmation interaction and the static/static-object event raise; check Debug output for subscription messages.
Attribution
Portions of this project are derived from or inspired by:
- ReactiveUI (e.g. Interaction pattern)
- reactivemarbles/ObservableEvents
See LICENSE for details.
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 is compatible. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- System.Reactive (>= 6.1.0)
-
.NETFramework 4.8
- System.Reactive (>= 6.1.0)
-
.NETStandard 2.0
- System.Reactive (>= 6.1.0)
-
.NETStandard 2.1
- System.Reactive (>= 6.1.0)
-
net10.0
- System.Reactive (>= 6.1.0)
-
net6.0
- System.Reactive (>= 6.1.0)
-
net7.0
- System.Reactive (>= 6.1.0)
-
net8.0
- System.Reactive (>= 6.1.0)
-
net9.0
- System.Reactive (>= 6.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 91 | 2/9/2026 |
| 1.0.0-beta2 | 91 | 2/9/2026 |
| 1.0.0-beta1 | 95 | 2/6/2026 |