ReflectionIT.DisposeGenerator 0.1.0-preview

Prefix Reserved
This is a prerelease version of ReflectionIT.DisposeGenerator.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package ReflectionIT.DisposeGenerator --version 0.1.0-preview
                    
NuGet\Install-Package ReflectionIT.DisposeGenerator -Version 0.1.0-preview
                    
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="ReflectionIT.DisposeGenerator" Version="0.1.0-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ReflectionIT.DisposeGenerator" Version="0.1.0-preview" />
                    
Directory.Packages.props
<PackageReference Include="ReflectionIT.DisposeGenerator" />
                    
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 ReflectionIT.DisposeGenerator --version 0.1.0-preview
                    
#r "nuget: ReflectionIT.DisposeGenerator, 0.1.0-preview"
                    
#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 ReflectionIT.DisposeGenerator@0.1.0-preview
                    
#: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=ReflectionIT.DisposeGenerator&version=0.1.0-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=ReflectionIT.DisposeGenerator&version=0.1.0-preview&prerelease
                    
Install as a Cake Tool

ReflectionIT.DisposeGenerator

A source generator package that implements the Dispose pattern.

Planned future support includes the async dispose pattern and unmanaged resources.

https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-disposeasync

NuGet package

Package Version
ReflectionIT.DisposeGenerator NuGet

Example

Install the NuGet package, then annotate a class or struct with the Disposable attribute.

Annotate properties or fields with the Dispose attribute. Use the SetToNull when the property or field holds a large object and should be set to null after disposal.

using ReflectionIT.DisposeGenerator.Attributes;

[Disposable]
public partial class LogWriter : IDisposable {

    [Dispose(SetToNull = true)]
    private StreamWriter StreamWriter { get; set; }

    public LogWriter(string path) => StreamWriter = new StreamWriter(path);

    public void WriteLine(string text) => StreamWriter.WriteLine($"{DateTime.Now}\t{text}");
}

This generates the following partial class, which disposes the StreamWriter property and sets it to null.

partial class LogWriter
{
    public void Dispose() {
        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
        Dispose(disposing: true);
        global::System.GC.SuppressFinalize(this);
    }

    private bool _isDisposed;

    protected virtual void Dispose(bool disposing) {
        if (!_isDisposed) {
            if (disposing) {
                StreamWriter?.Dispose();
            }
            StreamWriter = null;
            _isDisposed = true;
        }
    }
}

Implement the dispose pattern for a derived class

A class derived from a class that already implements IDisposable should not implement IDisposable again, because the base class implementation of IDisposable.Dispose is inherited by derived classes.

Set the OverrideDispose property of the Disposable attribute to true. In that case, the public parameterless Dispose method is not generated, and the protected Dispose(bool) method is generated as an override.

[Disposable(OverrideDispose = true)]
public partial class SecondLogWriter : LogWriter {
                
    [Dispose]
    private StreamWriter SecondStreamWriter { get; }
                
    public SecondLogWriter(string path) : base(path) => SecondStreamWriter = new StreamWriter(path + "2");
                
    public override void WriteLine(string text) {
        base.WriteLine(text);
        SecondStreamWriter.WriteLine($"{DateTime.Now}\t{text.ToUpper()}");
    }
}

This generates the following partial class, which disposes the SecondStreamWriter property.

partial class SecondLogWriter
{
    private bool _isDisposed;

    protected override void Dispose(bool disposing) {
        if (!_isDisposed) {
            if (disposing) {
                SecondStreamWriter?.Dispose();
            }
            _isDisposed = true;
        }
        base.Dispose(disposing);
    }
}

Thread-safe disposal

Use Interlocked.CompareExchange to ensure thread-safe disposal. Set the IsThreadSafe property of the Disposable attribute to true.

[Disposable(IsThreadSafe = true)]
public partial class LogWriter : IDisposable {

    [Dispose]
    private readonly StreamWriter _streamWriter;

    public LogWriter(string path) => _streamWriter = new StreamWriter(path);

    public void WriteLine(string text) => _streamWriter.WriteLine($"{DateTime.Now}\t{text}");
}

This generates the following partial class, which uses Interlocked.CompareExchange to ensure thread-safe disposal.

partial class LogWriter
{
    public void Dispose() {
        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
        Dispose(disposing: true);
        global::System.GC.SuppressFinalize(this);
    }

    private int _isDisposed;

    protected virtual void Dispose(bool disposing) {
        if (global::System.Threading.Interlocked.CompareExchange(ref _isDisposed, 1, 0) == 0) {
            if (disposing) {
                _streamWriter?.Dispose();
            }
        }
    }
}

License

This project is licensed under the MIT License - see the LICENSE file for details.

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 was computed.  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 was computed.  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 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  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.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.1-preview 49 6/4/2026
0.4.0-preview 59 4/29/2026
0.3.0-preview 55 4/28/2026
0.2.0-preview 59 4/20/2026
0.1.0-preview 53 4/20/2026