.NetCore Autofac.Core.DependencyResolutionException: Circular component dependency detected

依赖注入实现类循环引用导致错误

一次拉取代码之后编译、启动未出现错误,服务启动后调用API报错,错误信息如下:

.......
An unandled exception has occurred while executing the request.
Autofac.Core.DependencyResolutionException: An exception was thrown while activating
 UOM.Service.DomainService.MachineDomainService -> 
 UOM.Service.DomainService.ServiceNodeDomainService -> 
 UOM.Service.DomainService.ServiceDomainService.
 ---> Autofac.Core.DependencyResolutionException: Circular component dependency 
 detected: UOM.Service.DomainService.MachineDomainService -> 
 UOM.Service.DomainService.ServiceNodeDomainService -> 
 UOM.Service.DomainService.ServiceDomainService -> 
 UOM.Service.DomainService.ServiceNodeDomainService.
   at Autofac.Core.Resolving.CircularDependencyDetector.CheckForCircularDependency(IComponentRegistration registration, Stack`1 activationStack, Int32 callDepth)
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Activators.Reflection.AutowiringParameter.<>c__DisplayClass0_0.<CanSupplyValue>b__0()
   at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()
   at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget)
   --- End of inner exception stack trace ---
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget)
   at Autofac.Core.Resolving.InstanceLookup.Execute()
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
......

错误分析

错误信息解读

  1. Autofac.Core.DependencyResolutionException: An exception was thrown while activating
    翻译为激活时抛出异常,意思是无法创建接口的实例
  2. Autofac.Core.DependencyResolutionException: Circular component dependency
    翻译为组件形成循环引用

寻找循环

UOM.Service.DomainService.MachineDemainService -> 
UOM.Service.DomainService.ServiceNodeDomainService -> 
UOM.Service.DomainService.ServiceDomainService -> 
UOM.Service.DomainService.ServiceNodeDomainService.

编号
① MachineDomainService
② ServiceNodeDomainService
③ ServiceDomainService
.NetCore 依赖注入循环引用
查看服务代码后的确是存在循环引用

反思

在此次事件中,由于没有进行评估和详细设计,直接进行编码,从而没有把类的职责划分清楚,所以导致循环引用。实际上可以设置允许循环引用

builder.RegisterType<UserService>()
 .InstancePerLifetimeScope()
 .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);

这种处理方式只会导致问题变得越来越糟糕,应当解除循环引用和减少耦合度,提高代码的可维护性。如果项目非常紧急可以这样在处理(给自己挖坑)

在实际工作容易出现循环依赖的场景有:

  1. 同一个工程不同模块依赖注入;
  2. 多个过程进行项目;
  3. 多个服务进行通信(Http、MQ、Rpc)等。

保持类、模块、服务的自治性,尽量不要形成依赖。单体服务设计时同一层次不要直接引用,尽量创建自身能够控制的实体,调用方(高层级)将需要依赖的转为该实体传入,降低耦合度。微服务中尽量少用Rpc,避免滥用,如果非要用也必须统一管理。服务数量过多时,是否存在循环依赖则需要进行整体结构的宏观把握,理清楚服务间的关系,进行良好的服务划分,怎么划分服务则需要根据具体业务分析和经验了。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值