In high-performance ASP.NET Core development, Dapper is often favored for its "close to the metal" execution speeds. However, Dapper is a "Micro-ORM," which means it handles the mapping of data but leaves the management of database connections entirely in your hands.
If you don't master connection pooling, your high-performance API will eventually hit a wall, resulting in the dreaded TimeoutException: Connection pool exhausted.
1. Understanding the Mechanics
Connection pooling is a service provided by the underlying ADO.NET driver (like Microsoft.Data.SqlClient). Instead of destroying a connection when you are done, the driver "recycles" it into a pool.
The Lifecycle of a Pooled Connection:
Request: You call
connection.Open(). The driver looks for an idle connection in the pool.Execution: Dapper executes your SQL using that connection.
Release: You call
connection.Dispose(). The driver resets the connection state and puts it back in the pool.
The Golden Rule: You do not manage the pool; you manage the individual connection's lifecycle. If you fail to dispose of a connection, it cannot return to the pool, creating a "leak."
2. Setting Up the Infrastructure
The modern standard for managing Dapper connections in ASP.NET Core is using a connection factory combined with dependency injection.
The Connection Factory Pattern
This pattern abstracts the creation of the connection, ensuring your business logic doesn't need to know about connection strings or specific providers.
public interface IDbConnectionFactory
{
Task<IDbConnection> CreateConnectionAsync();
}
public class SqlServerConnectionFactory : IDbConnectionFactory
{
private readonly string _connectionString;
public SqlServerConnectionFactory(string connectionString)
{
_connectionString = connectionString;
}
public async Task<IDbConnection> CreateConnectionAsync()
{
var connection = new SqlConnection(_connectionString);
await connection.OpenAsync();
return connection;
}
}
Dependency Injection (Program.cs)
Register the factory as a Singleton since it only needs to hold the connection string configuration.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddSingleton<IDbConnectionFactory>(_ =>
new SqlServerConnectionFactory(connectionString!));
Join the conversation! Your thoughts help the community grow.