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

22次阅读

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

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

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:

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

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

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

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

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

text=ZqhQzanResources