DisposableHelpers by Clynt Neiko Rupinta
Nuget / site data
Details
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
Original Readme
DisposableHelpers
Disposable helpers for IDisposable and IAsyncDisposable with source generators. Also capable of both anonymous disposable and anonymous async disposable.
NuGets
Name | Info |
---|---|
DisposableHelpers |
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!.
About
Generating boilerplate for thread safe Dispose
How to use
Example ( source csproj, source files )
- CSharp Project
- Program.cs
- DALDB.cs
- ConnectionDB.cs
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>
This is the use of DisposableHelpers in Program.cs
using IDisposableGeneratorDemo;
//https://github.com/benutomo-dev/RoslynComponents
using (var db = new DALDB())
{
Console.WriteLine("before releasing");
}
Console.WriteLine("after releasing");
This is the use of DisposableHelpers in DALDB.cs
using DisposableHelpers.Attributes;
using System.Resources;
namespace IDisposableGeneratorDemo;
[Disposable]
partial class DALDB
{
private readonly ConnectionDB cn;
private readonly ConnectionDB cn1;
public DALDB()
{
cn = new ConnectionDB();
cn1=new ConnectionDB();
}
protected void Dispose(bool disposing)
{
if (disposing)
{
cn.Dispose();
cn1.Dispose();
}
}
}
This is the use of DisposableHelpers in ConnectionDB.cs
namespace IDisposableGeneratorDemo;
class ConnectionDB : IDisposable
{
public void Dispose()
{
Console.WriteLine("disposing connectiondb");
}
}
Generated Files
Those are taken from $(BaseIntermediateOutputPath)\GX
- IDisposableGeneratorDemo.DALDB.cs
// <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