RSCG – Dirge
| name | Dirge |
| nuget | https://www.nuget.org/packages/Dirge/ |
| link | https://github.com/IkuzakIkuzok/Dirge |
| author | Kazuki Kohzuki |
Dirge is a Roslyn-based code generator that automatically implements the `IDisposable` pattern for C# classes.
Key Features:
1. AutoDispose Attribute: Mark any partial class with `[AutoDispose]` to automatically generate `Dispose()` and `Dispose(bool)` methods.
2. Automatic Field Disposal: The generator detects all disposable fields and automatically calls `.Dispose()` on them in the correct order.
This is how you can use Dirge .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dirge" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
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;
[Dirge.AutoDispose]
partial class DALDB
{
private ConnectionDB cn;
private ConnectionDB cn1;
public DALDB()
{
cn = new ConnectionDB();
cn1=new ConnectionDB();
}
}
namespace IDisposableGeneratorDemo;
class ConnectionDB : IDisposable
{
static int count = 0;
public ConnectionDB()
{
Interlocked.Increment(ref count);
}
public void Dispose()
{
Console.WriteLine($"disposing connectiondb {Interlocked.Decrement(ref count)}");
}
}
The code that is generated is
// <auto-generated/>
#pragma warning disable CS0282
namespace IDisposableGeneratorDemo
{
partial class DALDB : global::System.IDisposable
{
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Diagnostics.DebuggerBrowsable(global::System.Diagnostics.DebuggerBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGenerated]
private bool __generated_disposed = false;
public void Dispose()
{
Dispose(true);
global::System.GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (this.__generated_disposed) return;
try
{
if (disposing)
{
this.cn?.Dispose();
this.cn1?.Dispose();
}
}
finally
{
this.__generated_disposed = true;
}
}
}
}
// <auto-generated />
#nullable enable
namespace Dirge
{
[global::System.AttributeUsage(global::System.AttributeTargets.Class | global::System.AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
internal sealed class AutoDisposeAttribute : global::System.Attribute
{
public string? ReleaseUnmanagedResources { get; set; } = null;
internal AutoDisposeAttribute() { }
}
}
// <auto-generated />
namespace Dirge
{
[global::System.AttributeUsage(global::System.AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
internal sealed class DoNotDisposeAttribute : global::System.Attribute
{
internal DoNotDisposeAttribute() { }
}
}
// <auto-generated />
namespace Dirge
{
[global::System.AttributeUsage(global::System.AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
internal sealed class DoNotDisposeWhenAttribute : global::System.Attribute
{
internal string FlagName { get; }
internal bool FlagCondition { get; }
internal DoNotDisposeWhenAttribute(string flagName, bool flagCondition)
{
this.FlagName = flagName;
this.FlagCondition = flagCondition;
}
}
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/Dirge