Dapper怎么与依赖注入容器(如Autofac)集成 Dapper高级DI配置

来源:这里教程网 时间:2026-02-21 17:36:17 作者:

Dapper 本身是个轻量级的 SQL 映射工具,不内置依赖注入能力,所以要和 Autofac 这类容器集成,关键不是“让 Dapper 支持 DI”,而是把 Dapper 依赖的核心对象(如 IDbConnection)和仓储类(Repository)注册进容器,并控制其生命周期。高级配置的核心在于连接管理、作用域隔离和线程安全,而不是强行包装 Dapper。

注册 IDbConnection 实例(按请求作用域)

Dapper 操作依赖 IDbConnection,但直接注册 SqlConnection 会出问题——它不是线程安全的,也不能跨请求复用。正确做法是注册一个工厂或委托,在每次需要时创建新连接:

在 Autofac 模块中用
InstancePerLifetimeScope()
注册连接工厂,比如
Func<idbconnection></idbconnection>
实际实现可封装为
DbConnectionFactory
,读取配置字符串后 new SqlConnection 并 Open()
避免注册单个 SqlConnection 实例,否则高并发下容易报“连接已关闭”或“连接池已满”

仓储类注册与构造注入

仓储类(如

ProductRepository
)应只依赖
IDbConnection
,不要自己 new 连接:

接口定义清晰:例如
IProductRepository
,方法不暴露连接细节
实现类通过构造函数接收
IDbConnection
,由 Autofac 自动注入
注册时使用
AsImplementedInterfaces().InstancePerLifetimeScope()
,确保每个 Web 请求(或作用域)内复用同一仓储实例,同时连接也是该作用域内的

处理事务与共享连接(高级场景)

当多个仓储需参与同一事务时,不能各自 new 连接——必须共享同一个打开的连接和 Transaction:

IDbConnection
IDbTransaction
都注册为
InstancePerLifetimeScope()
在业务服务层(如
OrderService
)中显式 BeginTransaction,并传给各仓储,或通过上下文(如 AsyncLocal)隐式透传
推荐方式:封装一个
UnitOfWork
类,持有一个连接+事务,在作用域结束前统一 Commit 或 Rollback

数据库类型切换与多实例支持

如果项目要兼容 SQL Server、MySQL、PostgreSQL 等多种数据库,别硬编码 SqlConnection:

抽象出
IDbProvider
接口,按配置返回对应 DbConnection 类型(如 MySqlConnection、NpgsqlConnection)
在 Autofac 中根据 appsettings.json 的
DBType
动态注册不同 provider 和 connection 工厂
避免静态字段缓存连接字符串或连接实例,防止配置热更新失效或测试干扰

基本上就这些。Dapper 的 DI 集成不复杂但容易忽略连接生命周期,核心就三点:连接不复用、仓储随作用域、事务靠共享。只要连接管好了,Dapper 就能稳稳跑在 Autofac 之上。

相关推荐

热文推荐