.NET Core Web API中Autofac激活服务检测到循环组件依赖问题求助
问题原因
当前报错是典型的构造函数循环依赖问题:AfterSaleService 构造函数依赖 IOrderService,同时 OrderService 构造函数也依赖 IAfterSaleService,Autofac初始化实例时需要先完成依赖项的构造,两个服务互相等待对方初始化完成,因此抛出依赖解析异常。
解决方案
方案1(优先推荐):重构代码拆分依赖
从设计层面打破循环是最优解,将两个服务中互相调用的公共逻辑抽离为第三个独立服务,比如新建 IOrderAfterSaleShareService 接口和对应实现,把原来两个服务里需要互相调用的方法都放到这个新服务中,让OrderService和AfterSaleService都依赖这个新服务,即可完全消除循环依赖。
方案2:使用Lazy延迟解析
Autofac原生支持Lazy<T>类型的注入,依赖项只会在第一次访问Value属性时才会被解析,不会阻塞构造函数的初始化,改造成本极低,无需修改服务注册代码,仅调整其中一个服务的依赖声明即可:
public class OrderService : IOrderService { private IOrderDal _orderDal; private ICustomerService _customerService; private IProductService _productService; private IOrderDetailService _orderDetailService; // 改为Lazy<IAfterSaleService>类型 private Lazy<IAfterSaleService> _afterSaleService; public OrderService( IOrderDal orderDal, ICustomerService customerService, IProductService productService, IOrderDetailService orderDetailService, Lazy<IAfterSaleService> afterSaleService) { _orderDal = orderDal; _customerService = customerService; _productService = productService; _orderDetailService = orderDetailService; _afterSaleService = afterSaleService; } // 后续使用售后服务的地方,通过_afterSaleService.Value访问即可 }
方案3:使用属性注入
属性注入是在实例构造完成后再给属性赋值,也可以绕过构造阶段的循环依赖,需要修改服务注册和对应服务的代码:
- 调整服务注册代码,开启属性注入:
// 给两个循环依赖的服务都加上PropertiesAutowired() builder.RegisterType<AfterSaleService>().As<IAfterSaleService>().SingleInstance().PropertiesAutowired(); builder.RegisterType<OrderService>().As<IOrderService>().SingleInstance().PropertiesAutowired();
- 修改其中一个服务,把循环依赖从构造参数移为public属性,以AfterSaleService为例:
public class AfterSaleService : IAfterSaleService { private IAfterSaleDal _afterSaleDal; // 从构造参数移除,改为public属性 public IOrderService OrderService { get; set; } public AfterSaleService(IAfterSaleDal afterSaleDal) { _afterSaleDal = afterSaleDal; } }
注意事项
除非是临时兼容旧代码,否则优先选择重构拆分的方案,循环依赖本质是代码职责划分不合理的表现,属性注入和延迟解析都只是兼容手段,无法解决设计层面的问题。
内容的提问来源于stack exchange,提问作者notcontrol
相关产品推荐
相关产品推荐

