Autofac中DataContext未随生命周期域刷新致批量导入性能问题
你的问题核心在于DbFactory的生命周期和实现逻辑导致DataContext无法随子LifetimeScope刷新,具体拆解如下:
DbFactory的实现缺陷:
你的DbFactory在构造函数里就直接初始化了DataContext,并且Initialise()方法只会返回已存在的实例,不会创建新的。这意味着只要DbFactory是同一个实例,它内部的DataContext就永远不会更新。DbFactory的注册范围问题:
你在循环的子LifetimeScope里只注册了UnitOfWork、业务服务和仓储,但没有重新注册DbFactory和DataContext。这导致子域里解析IDbFactory时,会从父容器获取实例——如果父容器里DbFactory是单例或者绑定到父域生命周期,那所有子域都会复用同一个DbFactory,自然DataContext也不会变。依赖链的传递失效:
你以为子域解析的UnitOfWork是新实例就会带动所有子依赖刷新,但UnitOfWork依赖的IDbFactory来自父容器,所以它拿到的还是旧的DbFactory,进而复用旧的DataContext。
针对这个问题,有两种清晰的修复路径,你可以根据项目架构选择:
路径一:修正DbFactory的生命周期与实现
1. 重构DbFactory代码
去掉构造函数里的提前初始化,让每个DbFactory实例对应一个全新的DataContext:
public class DbFactory : Disposable, IDbFactory { private DataContext _dbContext; // 移除构造函数里的DataContext初始化 public DbFactory() { } public DataContext Initialise() { return _dbContext ?? (_dbContext = new DataContext()); } protected override void DisposeCore() { _dbContext?.Dispose(); } }
2. 调整DbFactory的注册范围
在启动时的Autofac配置里,把DbFactory注册为和其他服务同生命周期的实例:
// 加入到你的AutofacConfig.InitialiseJobRunner()逻辑中 builder.RegisterType<DbFactory>().As<IDbFactory>() .InstancePerMatchingLifetimeScope(lifetimeScope);
3. 子域无需重复注册DbFactory
此时子LifetimeScope会自动继承父容器的注册规则,每次创建子域时都会生成新的DbFactory实例,进而创建新的DataContext。
路径二:移除DbFactory,让Autofac直接管理DataContext生命周期
如果你的DbFactory只是用来创建DataContext,可以直接简化依赖链,让Autofac全权负责DataContext的生命周期:
1. 重构UnitOfWork
直接依赖DataContext而非IDbFactory:
public class UnitOfWork : Disposable, IUnitOfWork { private readonly DataContext _dbContext; // 直接注入DataContext public UnitOfWork(DataContext dbContext) { _dbContext = dbContext; } public DataContext DbContext => _dbContext; public void Commit() { DbContext.Commit(); } }
2. 确保DataContext的注册范围正确
你已经在启动时注册了DataContext为InstancePerMatchingLifetimeScope(lifetimeScope),这个配置是对的,子域会自动创建新的DataContext实例。
3. 移除DbFactory相关代码
不再需要DbFactory,直接删除相关类和注册逻辑即可。
- 调试时可以在
DataContext的构造函数里加日志,确认每次子域处理时是否有新实例被创建。 - 避免在循环里重复注册相同的服务(比如你的子域里注册的
UnitOfWork等),如果启动时已经注册了正确的生命周期,子域会自动继承,不需要重复注册。
内容的提问来源于stack exchange,提问作者Ciaran Gallagher

