Dapper 可无缝集成 ASP.NET Core DI 容器,需将 IDbConnection 或仓储服务注册为 Scoped 生命周期,避免 Singleton 导致连接复用;推荐封装为接口+实现类并注入 IDbConnection;事务需显式管理。

Dapper 本身是一个轻量级的 ORM 工具,不内置依赖注入(DI)能力,但它可以无缝集成到 ASP.NET Core 的 DI 容器中。关键在于:把 IDbConnection 或封装好的仓储/服务注册为 DI 服务,并确保生命周期合理(如 Scoped),避免连接泄漏或跨请求复用。
注册 IDbConnection(推荐 Scoped)
不要直接注册 SqlConnection 实例,而应注册一个工厂委托或封装类,让每次请求都创建新连接:
- 在
Program.cs中配置连接字符串并注册连接工厂:
var connectionString = builder.Configuration.GetConnectionString("Default");
builder.Services.AddScoped(sp =>
new SqlConnection(connectionString)); ⚠️ 注意:必须用 Scoped(不能是 Singleton),因为 SqlConnection 不是线程安全的,且需随请求释放。
封装 Dapper 操作为服务(推荐方式)
更清晰、可测试、易维护的做法是定义接口 + 实现类,把 Dapper 逻辑封装进去:
- 定义仓储接口:
IUserRepository - 实现类中通过构造函数注入
IDbConnection:
public class UserRepository : IUserRepository
{
private readonly IDbConnection _connection;
public UserRepository(IDbConnection connection) => _connection = connection;
public async Task GetById(int id) =>
await _connection.QueryFirstOrDefaultAsync(
"SELECT * FROM Users WHERE Id = @Id", new { Id = id });
}
- 注册服务:
services.AddScoped();
避免常见陷阱
几个高频出错点要特别注意:
- 别在 Singleton 服务里持有 IDbConnection:会导致连接被多个请求共用,可能抛出“连接已关闭”或并发异常
-
手动调用 Open() 要谨慎:Dapper 大多数方法(如
QueryAsync)会自动打开关闭连接,但如果你显式调用了Open(),记得配对Close()或用using -
事务需显式管理:若要用事务,建议注入
IDbTransaction或在服务中用_connection.BeginTransaction(),并在仓储方法中传入
进阶:支持多数据库(如 SQL Server + PostgreSQL)
可通过泛型仓储或工厂模式解耦:
- 注册不同连接类型:
services.AddScoped() - 仓储构造函数接收工厂而非裸连接,按需创建对应连接
- 配合
IOptions动态切换连接字符串
基本上就这些。Dapper 和 DI 结合不复杂,核心就三点:连接生命周期对、封装有接口、事务自己管。










