NCode.Disposables 5.3.0

Prefix Reserved
dotnet add package NCode.Disposables --version 5.3.0
                    
NuGet\Install-Package NCode.Disposables -Version 5.3.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="NCode.Disposables" Version="5.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NCode.Disposables" Version="5.3.0" />
                    
Directory.Packages.props
<PackageReference Include="NCode.Disposables" />
                    
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 NCode.Disposables --version 5.3.0
                    
#r "nuget: NCode.Disposables, 5.3.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 NCode.Disposables@5.3.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=NCode.Disposables&version=5.3.0
                    
Install as a Cake Addin
#tool nuget:?package=NCode.Disposables&version=5.3.0
                    
Install as a Cake Tool

ci Nuget

NCode.Disposables

A comprehensive .NET library providing useful IDisposable and IAsyncDisposable implementations for common resource management patterns.

Features

Core Implementations

  • Empty Disposable - No-op singleton for null object pattern
  • Action Disposable - Execute a delegate on dispose (idempotent)
  • Aggregate Disposable - Wrapper with replaceable underlying resource
  • Collection Disposable - Manage multiple disposables with LIFO disposal order
  • Context Disposable - Dispose on a specific SynchronizationContext (e.g., UI thread)
  • Shared Reference - Reference-counted resource sharing with lease pattern

Async Support

All implementations have async counterparts (IAsyncDisposable):

  • AsyncDisposable.Empty, Create(), Aggregate(), Collection(), Shared()
  • AsyncDisposableAdapter - Wraps IDisposable as IAsyncDisposable

Extension Methods

  • DisposeAsyncIfAvailable() - Calls DisposeAsync if available, otherwise Dispose
  • DisposeAll() / DisposeAllAsync() - Dispose all items in a collection (LIFO order)
  • AsSharedReference() - Convert a disposable to a shared reference with leasing

Quick Reference

Feature Sync API Async API
Empty (no-op) Disposable.Empty AsyncDisposable.Empty
Action callback Disposable.Create(action) AsyncDisposable.Create(func)
Aggregate wrapper Disposable.Aggregate(disposable) AsyncDisposable.Aggregate(disposable)
Collection Disposable.Collection(items) AsyncDisposable.Collection(items)
Shared reference SharedReference.Create(value) AsyncSharedReference.Create(value)
Context disposal Disposable.Context(disposable, ctx)
Adapt sync→async AsyncDisposable.Adapt(disposable)

Usage Examples

Empty Disposable

// Singleton instance - useful as default/placeholder
IDisposable disposable = Disposable.Empty;
disposable.Dispose(); // no-op

Action Disposable

// Execute cleanup logic on dispose (idempotent - runs only once)
IDisposable disposable = Disposable.Create(() => Console.WriteLine("Disposed!"));
disposable.Dispose(); // prints "Disposed!"
disposable.Dispose(); // no-op

Aggregate Disposable

// Wrapper allowing the underlying resource to be swapped
var aggregate = Disposable.Aggregate(initialResource);
aggregate.Disposable = newResource; // swap resource
aggregate.Dispose(); // disposes current resource

Collection Disposable

// Manage multiple disposables - disposed in reverse (LIFO) order
var collection = Disposable.Collection(resource1, resource2, resource3);
collection.Add(resource4);
collection.Remove(resource2); // removed items are NOT disposed
collection.Dispose(); // disposes: resource4, resource3, resource1

Shared Reference (Reference Counting)

// Share a resource with reference counting
IDisposable resource = CreateExpensiveResource();
var lease1 = SharedReference.Create(resource);
var lease2 = lease1.AddReference();
var lease3 = lease2.AddReference();

lease1.Value.DoWork();
lease1.Dispose();

lease2.Value.DoWork();
lease2.Dispose();

lease3.Value.DoWork();
lease3.Dispose(); // resource disposed here (ref count = 0)

Context Disposable

// Dispose on a specific SynchronizationContext (e.g., UI thread)
var context = SynchronizationContext.Current;
var disposable = Disposable.Context(uiResource, context, async: false);
disposable.Dispose(); // runs on the context's thread

Async Adapter

// Wrap IDisposable as IAsyncDisposable
IDisposable syncResource = CreateResource();
IAsyncDisposable asyncResource = AsyncDisposable.Adapt(syncResource);
await asyncResource.DisposeAsync();

Extension Methods

// Dispose async if available, otherwise sync
await disposable.DisposeAsyncIfAvailable();

// Dispose all items in a collection (LIFO order)
var items = new object[] { resource1, resource2, nonDisposable, resource3 };
items.DisposeAll(); // disposes only IDisposable items, in reverse order

// Convert to shared reference
using var lease = myDisposable.AsSharedReference();

Feedback

Please provide any feedback, comments, or issues to this GitHub project here.

Release Notes

  • v1.0.0 - Initial release
  • v2.0.2 - Port to .NET Core/Standard
  • v3.0.0 - Port to .NET 8.0 and refactor shared reference implementation
  • v3.0.1 - Updated xml documentation
  • v3.1.0 - Split ISharedReference into ISharedReferenceScope and ISharedReferenceProvider
  • v4.0.0 - Revert the split
  • v4.1.0 - Added async support
  • v4.2.0 - Added async adapter
  • v4.3.0 - Added DisposeAsyncIfAvailable extension. Added idempotent option to certain methods.
  • v4.4.0 - Refactored the idempotent option to use function overloads.
  • v5.0.0 - Refactored shared references/leases to use structs
  • v5.0.1 - Removing dead code
  • v5.0.2 - Removing more dead code
  • v5.1.0 - Allow creating of async shared references without requiring async callsite
  • v5.1.1 - Minor resharper cleanup
  • v5.2.1 - Collections can be any object instead of just IDisposable or IAsyncDisposable
  • v5.3.0 - .NET 10 upgrade
Product Compatible and additional computed target framework versions.
.NET 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 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on NCode.Disposables:

Package Downloads
NCode.Collections.Providers

Default implementations for dynamic, change-aware collection providers. Includes static, observable, composite, and periodic polling data sources with automatic change notifications via IChangeToken. Provides dependency injection integration with Microsoft.Extensions.DependencyInjection.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.3.0 120 1/17/2026
5.2.1 202 11/29/2024
5.1.1 176 11/27/2024
5.1.0 191 5/16/2024
5.0.2 199 5/16/2024
5.0.1 206 5/16/2024
5.0.0 185 5/16/2024
4.4.0 187 5/15/2024
4.3.0 179 5/15/2024
4.2.0 185 4/29/2024
4.1.0 182 4/28/2024
4.0.0 178 4/21/2024
3.1.0 182 4/21/2024
3.0.1 178 4/21/2024
3.0.0 195 4/21/2024
2.0.2 1,700 1/22/2017
2.0.1 1,305 1/22/2017
1.0.1 1,688 2/11/2016
1.0.0 1,582 1/30/2016

Built on 2026-01-17 15:40:31Z