Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dispose of nested objects which all implement IDisposable

I have the following code in my project. Do I have to dispose the inner class explicit? If so where?

public class Outer : IDisposable
{
    Context context = new Context();
    Inner inner;

    public Outer()
    {
        inner = new Inner(context);
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

public class Inner : IDisposable
{
    Context context;

    public Inner(Context context)
    {
        this.context = context;
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

Context is something like DbContext from Entity Framework.

like image 992
LuckyStrike Avatar asked Feb 22 '23 14:02

LuckyStrike


1 Answers

Well, in this case you need to work out what should actually "own" the context. If you've got it in Inner, do you really need it in Outer as well? Which of them really takes responsibility for them? It looks to me like you really want:

public sealed class Outer : IDisposable
{
    private readonly Inner inner;

    public Outer()
    {
        inner = new Inner(new Context());
    }

    public void Dispose()
    {
        inner.Dispose();
    }
}

public sealed class Inner : IDisposable
{
    private readonly Context context;

    public Inner(Context context)
    {
        this.context = context;
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

Note that having made both Outer and Inner sealed, there's no need to write a protected Dispose(bool disposing) method etc - that's really for inheritance, which becomes a pain in general. If you really need to subclass Outer and Inner with the possibility of needing to dispose more resources, you'll need a more complicated implementations.

Personally I try not to implement IDisposable if possible, and keep disposable things only within local variables with using statements. It's not always possible of course, but it's worth trying...

like image 102
Jon Skeet Avatar answered Feb 25 '23 05:02

Jon Skeet