IDisposable pattern in .Net Core

·

2 min read

In .NET we have the power of GC. Meaning we are free to think and write code targetting what we want to achieve, and we leave the rest to our beloved CLR to do the heavy lifting for us. While this is true for most of the cases, there are instances where we would need to go deeper, what if we are handling un-manged code? Or how would we signal the release of a lock? This is where we implement the dispose pattern.

Few Points to consider when implementing the Dispose pattern.

  1. Your class should implement the IDisposable Interface

  2. Our class should have a prop to hold the Disposed state

  3. There should be a virtual method that is going to do the actual logic

  4. A finalizer is only required if you are directly referencing the un-managed resource

Now Let's Implement these 4 steps.

Let's assume that we have a class that has some unmanaged resources and we would need to clean them up once the object is destroyed.

Remember our friendly using block?? Well, we can only wrap a using block if that type has an implementation of the IDisposable interface.

public class BaseClassWithUnmanagedCode : IDisposable
{
    private bool _isDisposed = false;

    void Dispose()
    {
        Dispose(true);
        GC.SupressFinalize(this);
    }

    protected virtual void Dispose(bool isDiposing)
    {
        // Make sure that we are not double disposing.
        if(!_isDisposed)
        {
            if(isDiposing)
            {
                // Code for Managed resource
            }
            // Your un-managed free up.

           _isDisposed = true;
        }
    }
    // Finalizer
   ~BaseClassWithUnmanagedCode()=> Dispose(false);
}

Some Mentions:

GC.SuppressFinalise ensures that the destructor will not be called if the dispose has already run for the instance.

_isDisposed flag will ensure that we are not double disposing unnecessarily

The Virtual method ensures that we can override the behaviour if we are inheriting this class to another child class