Josupeit.Practices.Mixins.Disposable 1.0.9

Prefix Reserved
dotnet add package Josupeit.Practices.Mixins.Disposable --version 1.0.9
                    
NuGet\Install-Package Josupeit.Practices.Mixins.Disposable -Version 1.0.9
                    
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="Josupeit.Practices.Mixins.Disposable" Version="1.0.9">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Josupeit.Practices.Mixins.Disposable" Version="1.0.9" />
                    
Directory.Packages.props
<PackageReference Include="Josupeit.Practices.Mixins.Disposable">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
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 Josupeit.Practices.Mixins.Disposable --version 1.0.9
                    
#r "nuget: Josupeit.Practices.Mixins.Disposable, 1.0.9"
                    
#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 Josupeit.Practices.Mixins.Disposable@1.0.9
                    
#: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=Josupeit.Practices.Mixins.Disposable&version=1.0.9
                    
Install as a Cake Addin
#tool nuget:?package=Josupeit.Practices.Mixins.Disposable&version=1.0.9
                    
Install as a Cake Tool

Josupeit.Practices.Mixins.Disposable

Implementing IDisposable correctly is not hard in principle — check whether you have already disposed, release managed resources, release unmanaged resources, suppress finalization — but it is repetitive, and the repetition creates opportunities for subtle bugs: forgetting the idempotency check, not implementing IAsyncDisposable alongside IDisposable, or calling the wrong overload. When you have dozens of classes that own resources, that boilerplate adds up fast.

This meta-package installs a Roslyn source generator that writes the entire dispose implementation for you. You mark a class with [DisposableMixin], provide methods for the resources you actually own, and the generator produces a correct, idiomatic dispose pattern at compile time — no runtime overhead, no reflection.

dotnet add package Josupeit.Practices.Mixins.Disposable

The package is marked as a development dependency (DevelopmentDependency=true), so it does not appear as a runtime dependency in packages that consume your library.

How to use

Mark your class as partial and apply [DisposableMixin]. Then provide override points for the resource categories you own. You do not need to implement IDisposable or IAsyncDisposable yourself — the generator adds them.

using Josupeit.Practices.Mixins.Disposable;

[DisposableMixin]
public partial class DataExporter
{
    private readonly Stream _output = File.Create("export.bin");

    public async Task ExportAsync(IEnumerable<Record> records, CancellationToken cancellationToken)
    {
        ThrowIfDisposed(); // generated guard — call this at the start of every public method
        await WriteRecordsAsync(_output, records, cancellationToken);
    }

    // Override this if you own managed (disposable) resources.
    protected virtual void DisposeManagedResources()
    {
        _output.Dispose();
    }

    // Override this if you own managed resources that support async disposal.
    protected virtual async ValueTask DisposeManagedResourcesAsync()
    {
        await _output.DisposeAsync();
    }

    // Override this if you own unmanaged resources (handles, pointers, etc.).
    // protected virtual void DisposeUnmanagedResources() { ... }
}

The generator produces both IDisposable and IAsyncDisposable implementations by default on platforms that support it (netstandard2.1 and later). This mirrors the behavior of the BCL's own disposable types and avoids the awkwardness of implementing only one interface when callers might need the other.

Options

Pass a DisposableMixinOptions flags value to the attribute to tailor the generated code.

Flag Effect
WithProperty Generates a public bool IsDisposed { get; } property
WithEvent Generates a Disposing event that is raised when the instance is about to release its resources
WithoutIdempotencyGuarantees Omits the double-dispose guard — use only when you can guarantee Dispose is called once
WithoutAsyncDisposable Generates only IDisposable, not IAsyncDisposable
// Expose disposal state for UI binding or observability.
[DisposableMixin(DisposableMixinOptions.WithProperty | DisposableMixinOptions.WithEvent)]
public partial class ObservableConnection { … }

Analyzer and code fixes

The package also includes a Roslyn analyzer that catches common mistakes at compile time — for example, forgetting the partial keyword, using the wrong visibility on a cleanup method, or applying the mixin to a class that already inherits a disposable base. Most of these diagnostics come with a code fix you can apply directly from the IDE's lightbulb menu. The code fixes can also scaffold the DisposeManagedResources, DisposeManagedResourcesAsync, and DisposeUnmanagedResources method stubs for you.

For the full list of diagnostics and code fixes, see the Analyzer README.

For the complete generated member reference and generator limitations, see the Generator README.

There are no supported framework assets in this 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
1.0.9 108 3/30/2026
1.0.7 107 3/10/2026

- Fixes WithEvent documentation referring to a post-disposal event named Disposed
- Fixes package release notes items being joined with semicolons instead of newlines
- Embeds untracked sources in PDBs to fix NuGet Package Explorer warnings
- Fixes release notes being empty when packing at a tagged commit
- Fixes invalid NuGet dependency version ranges that prevented package push