激活 Autofac .NET Core Web 时检测到循环组件依赖性 API
Circular component dependency detected while activating Autofac .NET Core Web API
我对 IAfterSaleService 接口和 AfterSaleService Class 有问题,我对这些 cs 文件使用了 autofac IoC。然而,虽然我制作的构造函数注入适用于某些接口,但售后服务不适用于某些构造函数注入。例如,
虽然 IAfterService 在 AfterServiceController 的构造函数中工作,但它在同一目录中的其他服务(如 OrderService.cs...)的构造函数中不起作用
我收到以下异常响应
Autofac.Core.DependencyResolutionException: An exception was thrown while activating Retail.Business.Concretes.AfterSaleService -> Retail.Business.Concretes.OrderService.
---> Autofac.Core.DependencyResolutionException: Circular component dependency detected: Retail.Business.Concretes.AfterSaleService -> Retail.Business.Concretes.OrderService -> Retail.Business.Concretes.AfterSaleService.
具有以下堆栈跟踪:
at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
at Autofac.Core.Resolving.Pipeline.DefaultResolveRequestContext.ResolveComponent(ResolveRequest request)
at Autofac.Core.Activators.Reflection.AutowiringParameter.<>c__DisplayClass0_0.<CanSupplyValue>b__0()
at Autofac.Core.Activators.Reflection.BoundConstructor.Instantiate()
at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
at Autofac.Core.Activators.Reflection.ReflectionActivator.<ConfigurePipeline>b__11_0(ResolveRequestContext ctxt, Action`1 next)
at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
--- End of inner exception stack trace ---
at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.RegistrationPipelineInvokeMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.SharingMiddleware.<>c__DisplayClass5_0.<Execute>b__0()
at Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid id, Func`1 creator)
at Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid primaryId, Nullable`1 qualifyingId, Func`1 creator)
at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest request)
at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)
at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request)
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType)
at Autofac.Extensions.DependencyInjection.AutofacServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method429(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.<CreateActivator>b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
我的 IoC 喜欢如下。我说过 IAfterService 在以下服务的构造函数中不起作用
public class ContainerModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<AfterSaleService>().As<IAfterSaleService>().SingleInstance();
builder.RegisterType<EfAfterSaleDal>().As<IAfterSaleDal>().SingleInstance();
builder.RegisterType<ProductService>().As<IProductService>().SingleInstance();
builder.RegisterType<EfProductDal>().As<IProductDal>().SingleInstance();
builder.RegisterType<CustomerService>().As<ICustomerService>().SingleInstance();
builder.RegisterType<EfCustomerDal>().As<ICustomerDal>().SingleInstance();
builder.RegisterType<OrderService>().As<IOrderService>().SingleInstance();
builder.RegisterType<EfOrderDal>().As<IOrderDal>().SingleInstance();
builder.RegisterType<EfOrderDetailDal>().As<IOrderDetailDal>().SingleInstance();
builder.RegisterType<OrderDetailService>().As<IOrderDetailService>()
.SingleInstance();
}
}
但它在控制器的构造函数中有效
private IAfterSaleService _afterSaleService;
public AfterSalesController(IAfterSaleService afterSaleService)
{
_afterSaleService = afterSaleService;
}
它在与 AfterService.cs 相同的服务目录下不起作用,我希望它在 OrderService.cs 中起作用,因为我需要它
注意:其他服务(如 ICustomerService、IProductService...)仅在 OrderService 的构造函数中起作用 IAfterSaleService 不起作用
public class OrderService : IOrderService
{
private IOrderDal _orderDal;
private ICustomerService _customerService;
private IProductService _productService;
private IOrderDetailService _orderDetailService;
private IAfterSaleService _afterSaleService;
public OrderService(
IOrderDal orderDal,
ICustomerService customerService,
IProductService productService,
IOrderDetailService orderDetailService,
IAfterSaleService afterSaleService)
{
_orderDal = orderDal;
_customerService = customerService;
_productService = productService;
_orderDetailService = orderDetailService;
_afterSaleService = afterSaleService;
}
}
AfterService.cs
public class AfterSaleService : IAfterSaleService
{
private IAfterSaleDal _afterSaleDal;
private IOrderService _orderService;
public AfterSaleService(
IAfterSaleDal afterSaleDal, IOrderService orderService)
{
_afterSaleDal = afterSaleDal;
_orderService = orderService;
}
}
错误很明显:
Circular component dependency detected
你的 AfterSaleService
依赖于 IOrderService
而 OrderService
依赖于 IAfterSaleService
,很明显这将导致 DI 容器无法在构建过程中解析依赖关系。就我个人而言,我尽量不注入相同“级别”的依赖项,即存储库不接受存储库、服务——服务和控制器不依赖于其他控制器,所以我的建议是重构你的应用程序,这样你就不需要这样的注入(也许再引入一层或将公共代码移动到静态助手或其他东西)。
如果由于工作量而无法重写 ATM,您现在可以使用临时解决方案 - 注入与 Func
相同级别的依赖项。 Autofac
提供开箱即用的 Func
分辨率(即,如果您注册 IService
,则无需任何额外注册即可解析 Func<IService>
),因此您可以这样做:
public OrderService(..., Func<IAfterSaleService> afterSaleServiceFactory)
{
....
_afterSaleService = new Lazy<IAfterSaleService>(afterSaleServiceFactory);
}
和
public AfterSaleService(IAfterSaleDal afterSaleDal,
Func<IOrderService> orderServiceFactory)
{
_afterSaleDal = afterSaleDal;
_orderService = new Lazy<IAfterSaleService>(orderServiceFactory);
}
并使用延迟解析的依赖项 - _afterSaleService .Value
、_orderService.Value
UPD
实际上,Autofac 似乎也 supports Lazy
开箱即用,所以这会更容易:
public OrderService(..., Lazy<IAfterSaleService> afterSaleServiceFactory)
{
....
_afterSaleService = afterSaleService;
}
我对 IAfterSaleService 接口和 AfterSaleService Class 有问题,我对这些 cs 文件使用了 autofac IoC。然而,虽然我制作的构造函数注入适用于某些接口,但售后服务不适用于某些构造函数注入。例如, 虽然 IAfterService 在 AfterServiceController 的构造函数中工作,但它在同一目录中的其他服务(如 OrderService.cs...)的构造函数中不起作用
我收到以下异常响应
Autofac.Core.DependencyResolutionException: An exception was thrown while activating Retail.Business.Concretes.AfterSaleService -> Retail.Business.Concretes.OrderService. ---> Autofac.Core.DependencyResolutionException: Circular component dependency detected: Retail.Business.Concretes.AfterSaleService -> Retail.Business.Concretes.OrderService -> Retail.Business.Concretes.AfterSaleService.
具有以下堆栈跟踪:
at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
at Autofac.Core.Resolving.Pipeline.DefaultResolveRequestContext.ResolveComponent(ResolveRequest request)
at Autofac.Core.Activators.Reflection.AutowiringParameter.<>c__DisplayClass0_0.<CanSupplyValue>b__0()
at Autofac.Core.Activators.Reflection.BoundConstructor.Instantiate()
at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
at Autofac.Core.Activators.Reflection.ReflectionActivator.<ConfigurePipeline>b__11_0(ResolveRequestContext ctxt, Action`1 next)
at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
--- End of inner exception stack trace ---
at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.RegistrationPipelineInvokeMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.SharingMiddleware.<>c__DisplayClass5_0.<Execute>b__0()
at Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid id, Func`1 creator)
at Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid primaryId, Nullable`1 qualifyingId, Func`1 creator)
at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest request)
at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)
at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request)
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType)
at Autofac.Extensions.DependencyInjection.AutofacServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method429(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.<CreateActivator>b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
我的 IoC 喜欢如下。我说过 IAfterService 在以下服务的构造函数中不起作用
public class ContainerModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<AfterSaleService>().As<IAfterSaleService>().SingleInstance();
builder.RegisterType<EfAfterSaleDal>().As<IAfterSaleDal>().SingleInstance();
builder.RegisterType<ProductService>().As<IProductService>().SingleInstance();
builder.RegisterType<EfProductDal>().As<IProductDal>().SingleInstance();
builder.RegisterType<CustomerService>().As<ICustomerService>().SingleInstance();
builder.RegisterType<EfCustomerDal>().As<ICustomerDal>().SingleInstance();
builder.RegisterType<OrderService>().As<IOrderService>().SingleInstance();
builder.RegisterType<EfOrderDal>().As<IOrderDal>().SingleInstance();
builder.RegisterType<EfOrderDetailDal>().As<IOrderDetailDal>().SingleInstance();
builder.RegisterType<OrderDetailService>().As<IOrderDetailService>()
.SingleInstance();
}
}
但它在控制器的构造函数中有效
private IAfterSaleService _afterSaleService;
public AfterSalesController(IAfterSaleService afterSaleService)
{
_afterSaleService = afterSaleService;
}
它在与 AfterService.cs 相同的服务目录下不起作用,我希望它在 OrderService.cs 中起作用,因为我需要它 注意:其他服务(如 ICustomerService、IProductService...)仅在 OrderService 的构造函数中起作用 IAfterSaleService 不起作用
public class OrderService : IOrderService
{
private IOrderDal _orderDal;
private ICustomerService _customerService;
private IProductService _productService;
private IOrderDetailService _orderDetailService;
private IAfterSaleService _afterSaleService;
public OrderService(
IOrderDal orderDal,
ICustomerService customerService,
IProductService productService,
IOrderDetailService orderDetailService,
IAfterSaleService afterSaleService)
{
_orderDal = orderDal;
_customerService = customerService;
_productService = productService;
_orderDetailService = orderDetailService;
_afterSaleService = afterSaleService;
}
}
AfterService.cs
public class AfterSaleService : IAfterSaleService
{
private IAfterSaleDal _afterSaleDal;
private IOrderService _orderService;
public AfterSaleService(
IAfterSaleDal afterSaleDal, IOrderService orderService)
{
_afterSaleDal = afterSaleDal;
_orderService = orderService;
}
}
错误很明显:
Circular component dependency detected
你的 AfterSaleService
依赖于 IOrderService
而 OrderService
依赖于 IAfterSaleService
,很明显这将导致 DI 容器无法在构建过程中解析依赖关系。就我个人而言,我尽量不注入相同“级别”的依赖项,即存储库不接受存储库、服务——服务和控制器不依赖于其他控制器,所以我的建议是重构你的应用程序,这样你就不需要这样的注入(也许再引入一层或将公共代码移动到静态助手或其他东西)。
如果由于工作量而无法重写 ATM,您现在可以使用临时解决方案 - 注入与 Func
相同级别的依赖项。 Autofac
提供开箱即用的 Func
分辨率(即,如果您注册 IService
,则无需任何额外注册即可解析 Func<IService>
),因此您可以这样做:
public OrderService(..., Func<IAfterSaleService> afterSaleServiceFactory)
{
....
_afterSaleService = new Lazy<IAfterSaleService>(afterSaleServiceFactory);
}
和
public AfterSaleService(IAfterSaleDal afterSaleDal,
Func<IOrderService> orderServiceFactory)
{
_afterSaleDal = afterSaleDal;
_orderService = new Lazy<IAfterSaleService>(orderServiceFactory);
}
并使用延迟解析的依赖项 - _afterSaleService .Value
、_orderService.Value
UPD
实际上,Autofac 似乎也 supports Lazy
开箱即用,所以这会更容易:
public OrderService(..., Lazy<IAfterSaleService> afterSaleServiceFactory)
{
....
_afterSaleService = afterSaleService;
}