1

I wrote a class that inherits DbConnection and I'm not understanding fully why it works as it does.

At first I had this :

public class DatabaseConnection : DbConnection
{
    ... 
    public override void Close()
    {
        // Some stuff
    }   
    // No Dispose method
}

using(var db = new DatabaseConnection())
{
    // Some processing
}

The Close() method was not called, and we could see the connections staying on the MySQL server.


Now I have this, and it works (it really closes the connections, and the server is OK) :

public class DatabaseConnection : DbConnection, IDisposable
{
    ... 
    public override void Close()
    {
        // Some stuff
    }   

    public new void Dispose()
    {
        Close();
        base.Dispose();
        GC.SuppressFinalize(this);
    }
}

using(var db = new DatabaseConnection())
{
    // Some processing
}

Why inheriting the DbConnection class and overriding the Close() method doesn't work ?

Mickael V.
  • 1,109
  • 11
  • 21

2 Answers2

1

You can see in the reference source that DbConnection does not override Dispose, so Dispose will not call Close.

DbConnection inherits from Component, which is where the implementation of IDisposable is. You can see from the reference source that its Dispose(bool disposing) method is virtual, so you should override that:

protected override void Dispose(bool disposing)
{
    base.Dispose(disposing)
    Close();
}
Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • Some might argue that there is a "bug" in `DbConnection`, or at least in it's [documentation](https://msdn.microsoft.com/en-us/library/system.data.common.dbconnection.close(v=vs.110).aspx): "... close the connection by calling `Close` or `Dispose`, which are functionally equivalent." - but as we've seen, there's no guarantee that inheriting classes will maintain that function equivalency, when it could have easily have been made so (by at least having a "note to inheritors" or by explicitly coding this co-dependency). – Damien_The_Unbeliever May 31 '16 at 09:45
  • Thanks I see the logic there. That's very confusing with all the questions like [this](http://stackoverflow.com/questions/5243398/will-a-using-block-close-a-database-connection) showing a simple using() ! – Mickael V. May 31 '16 at 09:51
  • @MickaelV. it's especially confusing as (as Damien points out) the documentation says it works like that too. The comment on the answer to your linked question is valid, though: *In practice I doubt there are any DBConnection implementations that don't override Dispose and close any connections*. You're only noticing this because you're inheriting from the base class. – Charles Mager May 31 '16 at 09:53
0

The using statement calls the Dispose method at the end of the block.

Since the DbConnection also implements the IDisposable interface, the using block in the first snippet calls the inherited Dispose method.

The connection stays alive perhaps because you override the Close function, but I'm not sure in this, please correct me if I'm wrong.

Dombi Soma
  • 705
  • 1
  • 5
  • 11