m0ddixx
m0ddixx

Reputation: 43

Is it good practice to pass an already instanciated property into a using statement?

I came across this question when I was refactoring some of my code which was heavily depending on the Disposable pattern.

I do have a readonly field DbContext which is getting initialized in the constructor. Now I was wondering if I can just pass the field into a using block to get it disposed the right way. Or do I have to get rid of the field and the intialization to just initialize it within each using block

protected readonly DbContext _context;

public Repository(DbContext context)
{
    _context = context;
}

public Task<T> GetAsync(Guid id)
{
    using (_context)
    {
        return _context.Set<T>().FindAsync(new CancellationToken(), id);
    }
}

I expect to apply the Dispose pattern the right way

Upvotes: 2

Views: 90

Answers (1)

Daniel Crha
Daniel Crha

Reputation: 685

There are two potential issues I see:

  1. When you exit the using block, the object is disposed. If you then attempt to reuse it, you could get an InvalidOperationException thrown somewhere.
  2. Some objects do not release all of their managed resources when disposed. They may still be referencing some large-ish objects, which can't be garbage collected while you have a reference to the disposable object. Case in point: MemoryStream - when you dispose it, the MemoryStream does not unreference its internal byte[] buffer. That means that until you unreference the stream itself, the array can't be collected and is effectively a memory leak.

So from my point of view, it's good to create a new object in the using statement, since it automatically both disposes it for you, and unreferences it so it can be collected.

A possible solution could be to instead inject a Factory object, and use its factory method to create the disposable object at the start of the using block.

Upvotes: 5

Related Questions