Skip to main content

DisposableHelpers by Clynt Neiko Rupinta

Nuget / site data

Nuget GitHub last commit GitHub Repo stars

Details

Info

info

Name: DisposableHelpers

Disposable helpers for IDisposable and IAsyncDisposable.

Author: Clynt Neiko Rupinta

NuGet: https://www.nuget.org/packages/DisposableHelpers/

You can find more details at https://github.com/Kiryuumaru/DisposableHelpers

Source : https://github.com/Kiryuumaru/DisposableHelpers

Original Readme

note

DisposableHelpers

Disposable helpers for IDisposable and IAsyncDisposable with source generators. Also capable of both anonymous disposable and anonymous async disposable.

NuGets

NameInfo
DisposableHelpersNuGet

Installation

// Install release version
Install-Package DisposableHelpers

// Install pre-release version
Install-Package DisposableHelpers -pre

Supported frameworks

.NET Standard 2.0 and above - see https://github.com/dotnet/standard/blob/master/docs/versions.md for compatibility matrix

Usage

Disposable

using DisposableHelpers;

namespace YourNamespace
{
public class SampleDisposable : Disposable
{
private SampleUnmanagedResource resources;

protected override void Dispose(bool disposing)
{
if (disposing)
{
resources.Release();
}
base.Dispose(disposing);
}
}
}

Disposable Source Generator

using DisposableHelpers.Attributes;

namespace YourNamespace
{
[Disposable]
public partial class SampleDisposable
{
private SampleUnmanagedResource resources;

protected void Dispose(bool disposing)
{
if (disposing)
{
resources.Release();
}
base.Dispose(disposing);
}
}
}

Anonymous Disposable

using DisposableHelpers;

namespace YourNamespace
{
public static class Program
{
private static SampleUnmanagedResource resources;

public static void Main(string[] args)
{
Disposable disposable = new Disposable(disposing =>
{
if (disposing)
{
resources.Release();
}
});

disposable.Dispose();
}
}
}

AsyncDisposable

using DisposableHelpers;

namespace YourNamespace
{
public class SampleAsyncDisposable : AsyncDisposable
{
private SampleAsyncUnmanagedResource resources;

protected override async ValueTask Dispose(bool isDisposing)
{
if (isDisposing)
{
await resources.Release();
}
return base.Dispose(isDisposing);
}
}
}

AsyncDisposable Source Generator

using DisposableHelpers.Attributes;

namespace YourNamespace
{
[AsyncDisposable]
public partial class SampleAsyncDisposable
{
private SampleAsyncUnmanagedResource resources;

protected async ValueTask Dispose(bool isDisposing)
{
if (isDisposing)
{
await resources.Release();
}
return base.Dispose(isDisposing);
}
}
}

Anonymous AsyncDisposable

using DisposableHelpers;

namespace YourNamespace
{
public static class Program
{
private static SampleAsyncUnmanagedResource resources;

public static async void Main(string[] args)
{
AsyncDisposable disposable = new AsyncDisposable(async disposing =>
{
if (disposing)
{
await resources.Release();
}
});

await disposable.DisposeAsync();
}
}
}

Want To Support This Project?

All I have ever asked is to be active by submitting bugs, features, and sending those pull requests down!.

paypal

About

note

Generating boilerplate for thread safe Dispose

How to use

Example ( source csproj, source files )

This is the CSharp Project that references DisposableHelpers

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DisposableHelpers" Version="1.1.16" />
</ItemGroup>

</Project>

Generated Files

Those are taken from $(BaseIntermediateOutputPath)\GX

// <auto-generated/>
#pragma warning disable
#nullable enable
namespace IDisposableGeneratorDemo
{
partial class DALDB : global::System.IDisposable
{
#nullable disable
/// <summary>
/// Finalizes an instance of the <see cref = "Disposable"/> class.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
~DALDB()
{
Dispose(false);
}

/// <summary>
/// Gets a value indicating whether this object is in the process of disposing.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public bool IsDisposing => global::System.Threading.Interlocked.CompareExchange(ref disposeStage, DisposalStarted, DisposalStarted) == DisposalStarted;

/// <summary>
/// Gets a value indicating whether this object has been disposed.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public bool IsDisposed => global::System.Threading.Interlocked.CompareExchange(ref disposeStage, DisposalComplete, DisposalComplete) == DisposalComplete;

/// <summary>
/// Gets a value indicating whether this object has been disposed or is in the process of being disposed.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public bool IsDisposedOrDisposing => global::System.Threading.Interlocked.CompareExchange(ref disposeStage, DisposalNotStarted, DisposalNotStarted) != DisposalNotStarted;

/// <summary>
/// Gets the object name, for use in any <see cref = "global::System.ObjectDisposedException"/> thrown by this object.
/// </summary>
/// <remarks>
/// Subclasses can override this property if they would like more control over the object name appearing in any <see cref = "global::System.ObjectDisposedException"/>
/// thrown by this <see cref = "Disposable"/>. This can be particularly useful in debugging and diagnostic scenarios.
/// </remarks>
/// <value>
/// The object name, which defaults to the class name.
/// </value>

#nullable enable
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
protected virtual string? ObjectName => GetType().FullName;

#nullable disable
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
private const int DisposalNotStarted = 0;
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
private const int DisposalStarted = 1;
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
private const int DisposalComplete = 2;
// see the constants defined above for valid values
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
private int disposeStage;
/// <summary>
/// Occurs when this object is about to be disposed.
/// </summary>

#nullable enable
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public event global::System.EventHandler? Disposing;
/// <summary>
/// Disposes of this object, if it hasn't already been disposed.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public void Dispose()
{
if (global::System.Threading.Interlocked.CompareExchange(ref disposeStage, DisposalStarted, DisposalNotStarted) != DisposalNotStarted)
{
return;
}

OnDisposing();
Disposing = null;
Dispose(true);
global::System.GC.SuppressFinalize(this);
global::System.Threading.Interlocked.Exchange(ref disposeStage, DisposalComplete);
}

/// <summary>
/// Verifies that this object is not in the process of disposing, throwing an exception if it is.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
protected void VerifyNotDisposing()
{
if (IsDisposing)
{
throw new global::System.ObjectDisposedException(ObjectName);
}
}

/// <summary>
/// Verifies that this object has not been disposed, throwing an exception if it is.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
protected void VerifyNotDisposed()
{
if (IsDisposed)
{
throw new global::System.ObjectDisposedException(ObjectName);
}
}

/// <summary>
/// Verifies that this object is not being disposed or has been disposed, throwing an exception if either of these are true.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
protected void VerifyNotDisposedOrDisposing()
{
if (IsDisposedOrDisposing)
{
throw new global::System.ObjectDisposedException(ObjectName);
}
}

/// <summary>
/// Raises the <see cref = "Disposing"/> event.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("DisposableHelpers.SourceGenerators.DisposableGenerator", "1.0.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
protected virtual void OnDisposing()
{
Disposing?.Invoke(this, new global::System.EventArgs());
}
}
}

Usefull

Download Example (.NET C# )

Share DisposableHelpers

https://ignatandrei.github.io/RSCG_Examples/v2/docs/DisposableHelpers

In the same category (Disposer) - 3 other generators

BenutomoAutomaticDisposeImplSourceGenerator

Disposer

IDisposableGenerator