Autofac实现Unit of Work与EF6场景下的依赖注入问题咨询
问题根因
你出现报错的核心原因是C# 中接口不能直接被实例化,new ICustomerRepository(_context) 这种写法本身不符合语法规范,这和 Autofac 无关,属于基础语法错误。
适配依赖注入的改造方案
你原有代码在 UnitOfWork 构造函数内硬编码实例化 Repository 的写法,本身违背了依赖注入的核心原则:依赖应该由外部容器注入,而非内部主动创建。根据你的场景可以选择两种改造方案:
方案1:构造函数直接注入Repository(适合Repository数量少的场景)
直接调整 UnitOfWork 代码,把 Repository 作为构造参数传入,由 Autofac 负责实例化传递:
private readonly ContactsContext _context; public UnitOfWork(ContactsContext context, ICustomerRepository customersRepository) { _context = context; Customers = customersRepository; } public ICustomerRepository Customers { get; }
方案2:动态解析Repository(适合Repository数量多的场景)
如果后续会扩展大量 Repository,不想给构造函数加过多参数,可以注入 Autofac 的生命周期 scope 动态解析依赖:
private readonly ContactsContext _context; private readonly ILifetimeScope _scope; public UnitOfWork(ContactsContext context, ILifetimeScope scope) { _context = context; _scope = scope; } // 用到时再解析,避免构造函数冗余 public ICustomerRepository Customers => _scope.Resolve<ICustomerRepository>(new TypedParameter(typeof(ContactsContext), _context));
Autofac 依赖注册配置
完成代码改造后,需要在 Autofac 容器配置中注册所有依赖,示例如下:
var builder = new ContainerBuilder(); // 注册DbContext,通常设为请求级作用域,可根据业务调整生命周期 builder.RegisterType<ContactsContext>().InstancePerLifetimeScope(); // 注册Repository与对应接口的映射关系 builder.RegisterType<CustomerRepository>().As<ICustomerRepository>().InstancePerLifetimeScope(); // 注册UnitOfWork builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope(); // 构建容器 var container = builder.Build();
注意事项
- 所有关联依赖的生命周期要对齐:比如 DbContext 是请求级作用域,Repository 和 UnitOfWork 也要设为相同生命周期,避免出现上下文不一致问题
- 不需要手动在 UnitOfWork 中释放 DbContext,Autofac 会根据生命周期自动处理资源释放
- 如果没有定义 IUnitOfWork 接口,注册时可以省略
As<IUnitOfWork>()直接注册 UnitOfWork 本身
内容的提问来源于stack exchange,提问作者Computer
相关产品推荐
相关产品推荐

