NuExt.System
0.8.0
Prefix Reserved
dotnet add package NuExt.System --version 0.8.0
NuGet\Install-Package NuExt.System -Version 0.8.0
<PackageReference Include="NuExt.System" Version="0.8.0" />
<PackageVersion Include="NuExt.System" Version="0.8.0" />
<PackageReference Include="NuExt.System" />
paket add NuExt.System --version 0.8.0
#r "nuget: NuExt.System, 0.8.0"
#:package NuExt.System@0.8.0
#addin nuget:?package=NuExt.System&version=0.8.0
#tool nuget:?package=NuExt.System&version=0.8.0
NuExt.System
NuExt.System is a cross-platform application foundation for high-performance .NET desktop and hybrid frameworks, providing cohesive primitives for asynchrony, lifetime management, thread affinity, synchronization, observable state, cross-platform path processing, and high-performance memory operations across modern .NET, .NET Standard, and .NET Framework without heavy dependencies.
Why NuExt.System?
- Application-oriented — infrastructure for desktop and hybrid application frameworks, not just isolated helpers
- Framework-agnostic — works across WPF, WinForms, Avalonia, hybrid UI, services, and libraries
- Cross-platform — platform-independent primitives and explicit Windows and Unix path semantics
- Thread-aware — thread affinity, synchronization contexts, and sync/async coordination
- Lifetime-driven — deterministic cleanup for disposables, asynchronous resources, subscriptions, and services
- High-performance — span-based APIs, pooled buffers, and allocation-conscious builders
- Consistent across runtimes — a stable API surface across modern .NET, .NET Standard, and .NET Framework
- Dependency-light — no required hosting model, container, UI framework, or heavy external infrastructure
Designed for
NuExt.System is intended for application and framework authors who need:
- deterministic synchronous and asynchronous lifetime management;
- safe interaction with thread-affine objects and synchronization contexts;
- asynchronous events with ordered invocation, cancellation, and exception aggregation;
- observable collections and property notifications for application state;
- synchronous and asynchronous coordination primitives;
- Windows and Unix path processing independent of the host platform;
- compatibility across modern .NET and legacy .NET Framework targets.
Core infrastructure
Application object foundations
DisposableandAsyncDisposableprovide consistent, thread-safe base implementations for deterministic synchronous and asynchronous cleanup.PropertyChangeNotifierprovides synchronization-context-aware property notifications and reusable support for observable, thread-affine application state.
Lifetime management
LifetimeandAsyncLifetimecoordinate cleanup actions, subscriptions, disposables, and asynchronous resources as a single lifetime scope.- Cleanup actions execute in reverse registration order, with asynchronous cleanup and exception aggregation supported where applicable.
Threading and synchronization
AsyncLockandReentrantAsyncLockprovide synchronous and asynchronous coordination, cancellation, timeout handling, and explicit reentrancy semantics.AsyncWaitHandleintegrates wait handles with task-based asynchronous code.AsyncLazy<T>provides thread-safe, one-time asynchronous initialization with a cached, directly awaitable task.LockPoolassociates a stable lock with an object identity without relying on equality or hash codes, while allowing the lock lifetime to follow the key through weak references.SynchronizationContextHelper,SynchronizationContextExtensions, andThreadAffineSynchronizationContextprovide thread-affinity checks, context marshaling, synchronous and asynchronous invocation, result propagation, and exception handling.IDispatcherObject,ISynchronizeInvoker, and related contracts make thread-affine application infrastructure reusable across UI frameworks and hosting models.
Deterministic asynchronous events
NuExt.System treats an asynchronous event as an ordered asynchronous operation, not as an implicit parallel broadcast, making execution order, cancellation, and exception handling predictable.
public delegate ValueTask AsyncEventHandler(
object? sender,
EventArgs e,
CancellationToken cancellationToken);
public delegate ValueTask AsyncEventHandler<TEventArgs>(
object? sender,
TEventArgs e,
CancellationToken cancellationToken);
The design follows several principles:
- Cancellation is part of the operation contract —
CancellationTokenis a dedicated argument rather than application data embedded into a customEventArgstype. Handlers can inspect it directly and propagate it to downstream asynchronous APIs. - Synchronous completion remains inexpensive —
ValueTaskavoids requiring every handler to allocate aTaskwhen the work completes synchronously. - Invocation order is deterministic — handlers are awaited sequentially in subscription order. No hidden parallelism is introduced through
Task.WhenAll, so handlers can safely depend on ordering and observe preceding changes. - Exception behavior is explicit — invocation can stop on the first exception or continue through the remaining handlers and throw an
AggregateExceptionafterward. - Context flow is controlled by the caller — invocation overloads make continuation on the captured synchronization context an explicit choice.
Sequential invocation is the default because event handlers commonly interact with shared application state, thread-affine objects, and ordered lifecycle transitions. Applications that require parallel fan-out can still implement it explicitly at the point where independent execution is known to be safe.
Observable collections
ObservableDictionary<TKey, TValue>is a full observable dictionary rather than a thin wrapper aroundDictionary<TKey, TValue>. It implements dictionary and list-oriented contracts, preserves stable insertion order, provides index-aware collection notifications for individual changes, uses reset notifications for batch operations, and keepsCountand indexer property notifications consistent with each mutation.- The dictionary can participate directly in data-binding pipelines built around
INotifyCollectionChangedandINotifyPropertyChanged, including WPF, Avalonia, WinUI, .NET MAUI, and other UI or application frameworks that consume these standard interfaces. OrderedObservableCollection<T>maintains application-defined item ordering across inserts and moves while allowing explicit normalization when complete renumbering is required.ArrayEqualityComparer<T>provides structural array equality, whileReferenceEqualityComparerbackports BCL reference-identity comparison to older target frameworks.
Performance-oriented primitives
ValueListBuilder<T>uses caller-provided span storage first and grows throughArrayPool<T>only when necessary, making it suitable for short-lived internal lists without unconditional heap allocation.ValueStringBuilderfollows the same model for text construction: stack-backed or caller-provided storage for the common case, pooled growth for larger values, and a single resulting string allocation.ValuePathBuilderapplies the same allocation-conscious design to host-independent path construction and normalization.- Span-based compatibility APIs preserve newer BCL-style operations across older targets while using optimized implementation paths where the runtime permits them.
Host-independent path semantics
PathBuilder, ValuePathBuilder, and PathUtilities can process Windows and Unix paths independently of the host operating system. Path rules are selected explicitly through DirectorySeparatorChar or isUnixLike, rather than inherited implicitly from the host.
This is useful for build tools, archives, deployment systems, remote file systems, IDEs, and services that exchange paths between Windows and Unix environments. It avoids treating paths as unstructured strings or relying on separator replacement, which is insufficient for drive-relative, UNC, device, rooted, and relative path forms.
Span / MemoryExtensions Polyfills
This package includes polyfills (API backports) for selected Span / MemoryExtensions-style APIs from newer .NET versions. On modern runtimes, it transparently uses the inbox implementations; on older runtimes, it provides compatible behavior with the same semantics.
What you get (highlights)
- Search & comparison:
Contains,SequenceEqual(+IEqualityComparer<T>) - Indexing:
IndexOf,LastIndexOf(element / sequence) - Set-based search:
IndexOfAny,LastIndexOfAny,IndexOfAnyExcept,LastIndexOfAnyExcept - Range-based:
IndexOfAnyInRange,IndexOfAnyExceptInRange,LastIndexOfAnyInRange,LastIndexOfAnyExceptInRange - Utilities:
StartsWith,EndsWith,Replace(in-place / copy),Count,CountAny
Notes
- Allocation-free, performance-oriented; value types use bitwise fast paths where applicable.
- Semantics mirror the .NET runtime APIs; custom comparers are honored when provided.
Additional utilities
NuExt.System also includes focused helpers for delegates and asynchronous multicast invocation, enum metadata and formatting, exception throwing and validation, reflection, diagnostics and process monitoring, hexadecimal conversion, collection operations, string compatibility APIs, runtime attributes, and selected BCL polyfills.
Compatibility
- .NET Standard 2.0+, .NET 8/9/10, and .NET Framework 4.6.2+
- Designed primarily for desktop and hybrid application infrastructure
- Usable with WPF, WinForms, Avalonia, WinUI, Blazor Hybrid, console applications, services, and shared libraries
- Platform-independent APIs support Windows and Unix path semantics on any host OS
Quick Examples
1) Reentrant async lock
var asyncLock = new ReentrantAsyncLock();
asyncLock.Acquire(() =>
{
// Synchronous work with reentry allowed on the same flow.
});
await asyncLock.AcquireAsync(async () =>
{
await DoAsyncWork();
});
2) Async lifetime and aggregated disposal
var lifetime = new AsyncLifetime { ContinueOnCapturedContext = true };
lifetime.AddDisposable(new FileStream(path, FileMode.Open));
lifetime.AddAsync(FlushBuffersAsync);
await lifetime.DisposeAsync(); // Executes cleanup actions in reverse order
3) Allocation-conscious string building with ValueStringBuilder
Span<char> initial = stackalloc char[128];
var sb = new ValueStringBuilder(initial);
sb.Append("User: ");
sb.Append(userName);
sb.Append(", Items: ");
sb.Append(itemCount);
string result = sb.ToString(); // Allocates the resulting string
4) Host-independent path processing
using var windowsPath = new PathBuilder(@"C:\repo\src\..\artifacts")
{
DirectorySeparatorChar = '\\'
};
string normalizedWindowsPath = windowsPath.GetFullPath().ToString();
// C:\repo\artifacts, regardless of the host operating system
using var unixPath = new PathBuilder("/srv/app/../data")
{
DirectorySeparatorChar = '/'
};
string normalizedUnixPath = unixPath.GetFullPath().ToString();
// /srv/data, regardless of the host operating system
5) Ordered asynchronous events
AsyncEventHandler? changed = null;
changed += FirstHandlerAsync;
changed += SecondHandlerAsync;
await changed.InvokeAsync(this, EventArgs.Empty, cancellationToken);
Installation
Via NuGet:
dotnet add package NuExt.System
Or via Visual Studio:
- Go to
Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution.... - Search for
NuExt.System. - Click "Install".
Ecosystem
- NuExt.Minimal.Mvvm
- NuExt.Minimal.Mvvm.SourceGenerator
- NuExt.Minimal.Behaviors.Wpf
- NuExt.Minimal.Mvvm.Wpf
- NuExt.Minimal.Mvvm.MahApps.Metro
- NuExt.System.Data
- NuExt.System.Data.SQLite
Notes & acknowledgements
Some implementations are derived from the .NET Runtime (MIT). See LICENSE and source comments for attributions.
Contributing
Issues and PRs are welcome. Keep changes minimal and performance-conscious.
License
MIT. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. 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 is compatible. net463 was computed. net47 was computed. net471 is compatible. net472 was computed. net48 was computed. 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.6.2
- Microsoft.Bcl.HashCode (>= 6.0.0)
- System.Text.Json (>= 10.0.13)
-
.NETFramework 4.7.1
- Microsoft.Bcl.HashCode (>= 6.0.0)
- System.Text.Json (>= 10.0.13)
-
.NETStandard 2.0
- Microsoft.Bcl.HashCode (>= 6.0.0)
- System.Text.Json (>= 10.0.13)
-
.NETStandard 2.1
- System.Text.Json (>= 10.0.13)
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on NuExt.System:
| Package | Downloads |
|---|---|
|
NuExt.System.Data
Lightweight, provider-independent data access foundation for .NET, providing ADO.NET extensions for DataReader, DataRow, and DataTable, reusable DAL and database context abstractions, and deterministic database migrations with ordered execution and validated history tracking. |
|
|
NuExt.Presentation.Wpf
Lightweight WPF presentation infrastructure with XAML resources and styles, control and framework extensions, binding helpers, diagnostics, templating utilities, and window placement support. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.8.0 | 59 | 10/22/2026 |
| 0.7.8 | 295 | 10/14/2026 |
| 0.7.7 | 184 | 10/13/2026 |
| 0.7.6 | 381 | 10/2/2026 |
| 0.7.5 | 362 | 6/30/2026 |
| 0.7.4 | 270 | 6/29/2026 |
| 0.7.3 | 529 | 3/15/2026 |
| 0.7.2 | 253 | 3/2/2026 |
| 0.7.1 | 167 | 2/24/2026 |
| 0.7.0 | 291 | 2/12/2026 |
| 0.6.0 | 400 | 1/11/2026 |
| 0.5.2 | 450 | 12/15/2025 |
| 0.5.1 | 379 | 12/14/2025 |
| 0.4.1 | 590 | 12/10/2025 |
| 0.4.0 | 339 | 12/5/2025 |
| 0.3.5 | 408 | 6/13/2025 |
| 0.3.4 | 372 | 3/6/2025 |
| 0.3.3 | 521 | 2/21/2025 |
| 0.3.2 | 496 | 1/22/2025 |