Using Dependency Injection can have challenges, along with rewards.
System.InvalidOperationException: Cannot consume scoped service
Copyright 2020 Microsoft 🙂
This error occurred when I modified my AppLogging REST Service to have an internal service that logged errors directly to the database. Can’t have the AppLogging Service call itself if there’s an error right?
After the modification, I recieved the following error:
System.InvalidOperationException: Cannot consume scoped service 'Enterprise.Logging.Repository.Context.AppLogContext' from singleton 'WF.Library.Shared.Logging.IAppLocalLoggingSvc`1[Enterprise.Logging.App.Rest.Controllers.AppMastersController]'.
After some head tapping, I realized that I had modified the internal service class to now accept the DBContext, so that I could log errors directly to the database.
public AppLoggingSvc(AppLogContext appLogContext, IOptionsMonitor<WFAppSettings> appSettings)
I had the Dependency Injection (DI) setup like:
// Add DI reference to AppLoggingSvc that is a generic type
services.AddSingleton(typeof(IAppLocalLoggingSvc<>), typeof(Services.AppLoggingSvc<>));
I found the problem was that when you use AddDBContext to add the Database Context to your Dependency Injection collection, it is added as “Scoped”. So I was adding my IAppLocalLoggingSvc as a Singleton, but it was accepting a DI component in the constructor that was Scoped. These two scenarios are incompatible.
I found that using AddTransient resolved the issue:
// Add DI reference to AppLoggingSvc that is a generic type
services.AddTransient(typeof(IAppLocalLoggingSvc<>), typeof(Services.AppLoggingSvc<>));
Thanks for reading! Happy Coding.
Full Error Listing:
System.InvalidOperationException: Cannot consume scoped service 'Enterprise.Logging.Repository.Context.AppLogContext' from singleton 'WF.Library.Shared.Logging.IAppLocalLoggingSvc`1[Enterprise.Logging.App.Rest.Controllers.AppMastersController]'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.VisitScopeCache(ServiceCallSite scopedCallSite, CallSiteValidatorState state)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.VisitConstructor(ConstructorCallSite constructorCallSite, CallSiteValidatorState state)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.VisitRootCache(ServiceCallSite singletonCallSite, CallSiteValidatorState state)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateCallSite(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnCreate(ServiceCallSite callSite)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor(Type serviceType)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(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 where exception was thrown ---
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 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)