RSCG – GenerateDispose
| name | GenerateDispose |
| nuget | https://www.nuget.org/packages/GenerateDispose/ |
| link | https://github.com/ItaiTzur76/GenerateDispose |
| author | Itai Tzur |
GenerateDispose for boilerplate reduction for IDisposable pattern
Purpose
A Roslyn source generator that replaces the 10+ lines of IDisposable boilerplate code with a single attribute.
The code that you start with is
<project sdk="Microsoft.NET.Sdk">
<propertygroup>
<outputtype>Exe</outputtype>
<targetframework>net8.0</targetframework>
<implicitusings>enable</implicitusings>
<nullable>enable</nullable>
</propertygroup>
<propertygroup>
<emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
<compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
</propertygroup>
<itemgroup>
<packagereference version="1.0.1" include="GenerateDispose" includeassets="analyzers" privateassets="all">
</packagereference>
</itemgroup>
The code that you will use is
using IDisposableGeneratorDemo;
//https://github.com/benutomo-dev/RoslynComponents
using (var db = new DALDB())
{
Console.WriteLine("before releasing");
}
Console.WriteLine("after releasing");
namespace IDisposableGeneratorDemo;
[GenerateDispose.SourceGenerators.GenerateDispose(nameof(Drop))]
partial class DALDB :IDisposable
{
private ConnectionDB cn;
private ConnectionDB cn1;
public DALDB()
{
cn = new ConnectionDB();
cn1=new ConnectionDB();
}
public void Drop()
{
cn.Dispose();
cn1.Dispose();
}
}
namespace IDisposableGeneratorDemo;
class ConnectionDB : IDisposable
{
public void Dispose()
{
Console.WriteLine("disposing connectiondb");
}
}
The code that is generated is
namespace GenerateDispose.SourceGenerators;
/// <summary>
/// Specifies the method to be used for disposing objects of this class.
/// </summary>
/// <param name="disposeMethod">
/// The name of a method to be executed for disposing an object of this class.
/// This method must be one that can be invoked without providing any arguments.
/// <para>Note: there is no need to manually call "base.Dispose" from this method.</para>
///
[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
[global::System.AttributeUsage(global::System.AttributeTargets.Class)]
#pragma warning disable CS9113 // Parameter is unread.
internal class GenerateDisposeAttribute(string disposeMethod) : global::System.Attribute
#pragma warning restore CS9113 // Parameter is unread.
{ }
namespace IDisposableGeneratorDemo;
partial class DALDB : global::System.IDisposable
{
private int _isDisposed;
protected virtual void Dispose(bool disposing)
{
if (global::System.Threading.Interlocked.Exchange(ref _isDisposed, 1) != 1 && disposing)
{
Drop();
}
}
public void Dispose()
{
Dispose(disposing: true);
global::System.GC.SuppressFinalize(this);
}
}
// <auto-generated>
namespace Microsoft.CodeAnalysis
{
internal sealed partial class EmbeddedAttribute : global::System.Attribute
{
}
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/GenerateDispose