Dapper与Autofac集成的关键是正确注册IDbConnection工厂和仓储类并管理其生命周期。需用InstancePerLifetimeScope注册连接工厂避免线程安全问题,仓储类构造注入IDbConnection,事务场景共享同一连接和事务,多数据库支持通过IDbProvider抽象动态注册。

Dapper 本身是个轻量级的 SQL 映射工具,不内置依赖注入能力,所以要和 Autofac 这类容器集成,关键不是“让 Dapper 支持 DI”,而是把 Dapper 依赖的核心对象(如 IDbConnection)和仓储类(Repository)注册进容器,并控制其生命周期。高级配置的核心在于连接管理、作用域隔离和线程安全,而不是强行包装 Dapper。
注册 IDbConnection 实例(按请求作用域)
Dapper 操作依赖 IDbConnection,但直接注册 SqlConnection 会出问题——它不是线程安全的,也不能跨请求复用。正确做法是注册一个工厂或委托,在每次需要时创建新连接:
- 在 Autofac 模块中用
InstancePerLifetimeScope()注册连接工厂,比如Func - 实际实现可封装为
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 之上。










