Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Must I implement IDisposable on all classes, or is a base class sufficient?

I am told I need to dispose of instances of my Entity Framework repository classes and I created a base class to enforce this implementation.

I need to check with the experts: is it acceptable to implement IDisposable through a base class?

Note that the repository class has no class member variables.

/// Sample repository.  Note that I return List<T> as IEnumerable, 
/// and I use IDisposable 
///
public class CompanyRepository : DisposableBase, ICompanyRepository
{
    public IEnumerable<CompanyDetail> GetOneCompany(int? CompanyID)
    {
        var t = from c in _entities.CompanyDetail
                where c.CompanyID == CompanyID.Value
                select c;
        return t.ToList();
    }
}

/// <summary>
/// Disposable implementation based on advice from this link:
/// from Http://www.asp.net/entity-framework/tutorials/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
/// </summary>
public class DisposableBase : IDisposable
{
    protected TLSAdminEntities1 _entities;

    public DisposableBase()
    {
        _entities = new TLSAdminEntities1();
        disposed = false;
    }

    private bool disposed ;
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                _entities.Dispose();
            }
        }
        this.disposed = true;
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}
like image 787
makerofthings7 Avatar asked Nov 15 '11 15:11

makerofthings7


People also ask

When should you use IDisposable?

If you access unmanaged resources (e.g. files, database connections etc.) in a class, you should implement IDisposable and overwrite the Dispose method to allow you to control when the memory is freed.

Where is IDisposable used?

We should use an IDisposable design pattern (or Dispose Pattern) when we need to dispose of unmanaged objects. For implementing the IDisposable design pattern, the class which deals with unmanaged objects directly or indirectly should implement the IDisposable interface.

Why IDisposable interface is used?

Typically, types that use unmanaged resources implement the IDisposable or IAsyncDisposable interface to allow the unmanaged resources to be reclaimed. When you finish using an object that implements IDisposable, you call the object's Dispose or DisposeAsync implementation to explicitly perform cleanup.

Is IDisposable called automatically?

By default, the garbage collector automatically calls an object's finalizer before reclaiming its memory. However, if the Dispose method has been called, it is typically unnecessary for the garbage collector to call the disposed object's finalizer.

Is IDisposable an interface?

IDisposable is an interface that contains a single method, Dispose(), for releasing unmanaged resources, like files, streams, database connections and so on.


3 Answers

The answer is "it depends".

If the "Dispose()" method in some superclass is sufficient, you certainly don't need to reimplement it in each and every subclass.

The "superclass" might be the base class; it might be one or more subclasses.

It depends on what you allocate, and what needs to be cleaned up.

IMHO...

Here is what MSDN has to say:

http://msdn.microsoft.com/en-us/magazine/cc163392.aspx

When you derive from a disposable type, and that derived type does not introduce any new resources, then nothing special needs to be done. The base type IDisposable implementation will take care of cleaning up its resources and your subclass can be blissfully ignorant of the details.

<= In other words, you DON'T necessarily have to re-implement Dispose over and over

... but ...

However, it’s also common to have a subclass that does contain new resources that need to be cleaned up. In this case, your class needs to release its resources, while making sure that the base type’s resources also get released. Do this by overriding the cleanup method, releasing your resources, and then calling the base type to clean up its resources, as in Figure 6.

like image 106
paulsm4 Avatar answered Nov 05 '22 02:11

paulsm4


It depends on whether you have resources in the derived class that need to be disposed. If there are resources specific to the derived class, implementing IDisposable only on the base class will not be sufficient.

like image 44
James Johnson Avatar answered Nov 05 '22 04:11

James Johnson


Generaly spoken, you have to implement IDispoable in every class, where you have private members which themselves implement IDisposable. Those resources have to be "freed". I strongly advise you to read this very good paper on CodeProject about the IDisposable pattern.

like image 34
Fischermaen Avatar answered Nov 05 '22 04:11

Fischermaen