The correct answer is wrap them in a using
for the query or queries you want to use them for. Don't hold on to connections for longer then you immediately need. Doing so creates more problems then its worth.
In essence if you need a connection for a bunch of queries just wrap them in a using
statement, if they are separated by long running tasks, close them and open them on a piecemeal basis. The worst thing you can so is try to keep them open and check for if they are still alive.
SQL Server Connection Pooling (ADO.NET)
In practice, most applications use only one or a few different
configurations for connections. This means that during application
execution, many identical connections will be repeatedly opened and
closed. To minimize the cost of opening connections, ADO.NET uses an
optimization technique called connection pooling.
Furthermore
Connection pooling reduces the number of times that new connections
must be opened. The pooler maintains ownership of the physical
connection. It manages connections by keeping alive a set of active
connections for each given connection configuration. Whenever a user
calls Open
on a connection, the pooler looks for an available
connection in the pool. If a pooled connection is available, it
returns it to the caller instead of opening a new connection. When the
application calls Close
on the connection, the pooler returns it to
the pooled set of active connections instead of closing it. Once the
connection is returned to the pool, it is ready to be reused on the
next Open
call.
In the following example, three new SqlConnection objects are created, but only two connection pools are required to manage them.
Example from MSDN
using (SqlConnection connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=Northwind"))
{
connection.Open();
// Pool A is created.
}
using (SqlConnection connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=pubs"))
{
connection.Open();
// Pool B is created because the connection strings differ.
}
using (SqlConnection connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=Northwind"))
{
connection.Open();
// The connection string matches pool A.
}
For Controllers WCF services, and CQRS, they are usually short lived, so injecting them in a scoped life cycle is very common. However for things like button clicks in user applications, Service patterns calls, just use them when you need them. Never try to cache or pool.