ZeroAlloc.Notify is a source-generated notification library for .NET 8 and .NET 10. It provides async-first property and collection change notifications without reflection or dynamic dispatch. The Roslyn source generator eliminates runtime overhead by wiring all dispatch at compile time — no virtual dispatch, fully awaitable handlers.
dotnet add package ZeroAlloc.NotifyThe generator package must also be added as an analyzer:
<ItemGroup>
<PackageReference Include="ZeroAlloc.Notify.Generator" Version="*" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>// 1. Define a ViewModel with observable properties
[NotifyPropertyChangedAsync]
public partial class UserViewModel
{
[ObservableProperty]
private string _name = "";
[ObservableProperty]
private int _age;
}
// 2. Subscribe to async notifications
var vm = new UserViewModel();
vm.PropertyChangedAsync += async (args, ct) =>
{
Console.WriteLine($"Property '{args.PropertyName}' changed from {args.OldValue} to {args.NewValue}");
await Task.Delay(100, ct); // Non-blocking handler execution
};
// 3. Set properties — fully awaitable
await vm.SetNameAsync("Alice");
await vm.SetAgeAsync(30);ZeroAlloc.Notify provides async-first, fully awaitable handler dispatch — the only framework in this comparison where await vm.SetNameAsync(...) truly awaits all handlers. The async path runs at competitive speed with modest allocation (.NET 10, i9-12900HK, BenchmarkDotNet).
| Method | Mean | Alloc | vs Baseline |
|---|---|---|---|
Sync_INotifyPropertyChanged (baseline) |
21.41 ns | 24 B | — |
CommunityToolkit_SetName |
31.27 ns | 0 B | 1.47x slower |
Fody_SetName |
17.57 ns | 0 B | 1.22x faster |
ZeroAlloc_SetNameAsync |
61.84 ns | 48 B | 2.9x slower baseline, fully awaitable |
CommunityToolkit.Mvvm and PropertyChanged.Fody support sync notifications only — they cannot await async handlers. ZeroAlloc.Notify is the only framework in this comparison with first-class
ValueTaskhandler dispatch.
See docs/performance.md for detailed benchmark results and zero-allocation design explanation.
- Property Notifications — Strongly-typed, fully async
PropertyChangedAsyncevents - Collection Changes —
CollectionChangedAsyncwith observable property support - Data Validation —
INotifyDataErrorInfoAsyncfor async error collection - Sequential & Parallel —
[InvokeSequentially]attribute for handler ordering - Compiler Diagnostics — Missing handlers and misconfigurations caught at build time
- Async-First — Fully awaitable
ValueTaskhandlers; no fire-and-forget, no callbacks - Native AOT Compatible — No reflection at runtime; all dispatch resolved at compile time
- Source Generated — Full type safety with compile-time verification
| Topic | Description |
|---|---|
| Getting Started | Install and send your first notification in five minutes |
| Observable Properties | Defining and using observable properties |
| Async Notifications | Property and collection changed notifications with await support |
| Collection Changes | Observable collections with async event dispatch |
| Validation | INotifyDataErrorInfoAsync with async error handling |
| Performance | Zero-alloc internals, detailed benchmarks, Native AOT |
| Diagnostics | ZAN001–ZAN010 source generator warnings and errors |
| Advanced Patterns | Cancellation, scoped bindings, parallel handlers |
| Testing | Unit-testing observable models and notification flows |
See the samples directory for complete working examples:
- WPF MVVM application
- ASP.NET Core data binding
- Console property notifications
- Collection change handling
MIT