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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NuExt.System" Version="0.8.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NuExt.System" Version="0.8.0" />
                    
Directory.Packages.props
<PackageReference Include="NuExt.System" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NuExt.System --version 0.8.0
                    
#r "nuget: NuExt.System, 0.8.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NuExt.System@0.8.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NuExt.System&version=0.8.0
                    
Install as a Cake Addin
#tool nuget:?package=NuExt.System&version=0.8.0
                    
Install as a Cake Tool

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.

NuGet Ask DeepWiki Build License Downloads

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

  • Disposable and AsyncDisposable provide consistent, thread-safe base implementations for deterministic synchronous and asynchronous cleanup.
  • PropertyChangeNotifier provides synchronization-context-aware property notifications and reusable support for observable, thread-affine application state.

Lifetime management

  • Lifetime and AsyncLifetime coordinate 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

  • AsyncLock and ReentrantAsyncLock provide synchronous and asynchronous coordination, cancellation, timeout handling, and explicit reentrancy semantics.
  • AsyncWaitHandle integrates wait handles with task-based asynchronous code.
  • AsyncLazy<T> provides thread-safe, one-time asynchronous initialization with a cached, directly awaitable task.
  • LockPool associates 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, and ThreadAffineSynchronizationContext provide 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 — CancellationToken is a dedicated argument rather than application data embedded into a custom EventArgs type. Handlers can inspect it directly and propagate it to downstream asynchronous APIs.
  • Synchronous completion remains inexpensive — ValueTask avoids requiring every handler to allocate a Task when 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 AggregateException afterward.
  • 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 around Dictionary<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 keeps Count and indexer property notifications consistent with each mutation.
  • The dictionary can participate directly in data-binding pipelines built around INotifyCollectionChanged and INotifyPropertyChanged, 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, while ReferenceEqualityComparer backports BCL reference-identity comparison to older target frameworks.

Performance-oriented primitives

  • ValueListBuilder<T> uses caller-provided span storage first and grows through ArrayPool<T> only when necessary, making it suitable for short-lived internal lists without unconditional heap allocation.
  • ValueStringBuilder follows 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.
  • ValuePathBuilder applies 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:

  1. Go to Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution....
  2. Search for NuExt.System.
  3. Click "Install".

Ecosystem

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
Loading failed