dotnet-operator-sdk: Cannot resolve scoped service 'KubeOps.Operator.Controller.IEventQueue`1[MyOperator.Entities.V1DemoEntity]' from root provider
Describe the bug Not able to debug the sample operator in .Net 6.0. Getting the below exception.
To Reproduce
- Created the sample project via template
- Project is targeting KubeOps 6.5.3 and .Net 6.0
- Did dotnet run install
- Did dotnet run and got the below error
Startup Leader Elector for operator "myoperator". Unhandled exception. System.InvalidOperationException: Cannot resolve scoped service 'KubeOps.Operator.Controller.IEventQueue1[MyOperator.Entities.V1DemoEntity]’ from root provider.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, IServiceScope scope, IServiceScope rootScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at KubeOps.Operator.Builder.OperatorBuilder.<>c__DisplayClass18_0.<AddOperatorBase>b__3(ControllerRegistration r)
at System.Linq.Enumerable.SelectEnumerableIterator2.MoveNext() at System.Collections.Generic.List1.InsertRange(Int32 index, IEnumerable1 collection) at System.Collections.Generic.List1.AddRange(IEnumerable1 collection) at KubeOps.Operator.Controller.ResourceControllerManager.StartAsync(CancellationToken cancellationToken) at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken) at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token) at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token) at KubeOps.Operator.Commands.RunOperator.OnExecuteAsync() at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.InvokeAsync(MethodInfo method, Object instance, Object[] arguments) at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.OnExecute(ConventionContext context, CancellationToken cancellationToken) at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.<>c__DisplayClass0_0.<<Apply>b__0>d.MoveNext() --- End of stack trace from previous location --- at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 20 (12 by maintainers)
The latest functioning version seems to be 6.3.1
Same here, not fixed with latest version on nuget as of june 15
I’m still kind of baffled why there is a version 6.5.3, but no tag in github…
Ugh, I dislike the default DependencyInjection container, its errors aren’t the most useful. Using AutoFac, I’m not seeing any issues (https://github.com/Contrast-Security-OSS/agent-operator/blob/master/src/Contrast.K8s.AgentOperator/Startup.cs#L61) - pinned at a version close to latest.
Hopefully I’ll have time a bit later to repo this. I wonder if the assemblies got mixed up. The error looks correct.
ResourceControllerManageris added as a hosted service, which defaults to singleton scope. It’s requesting the activation ofIEventQueuewhich is bound in request scope via the activation of the transient scopedIManagedResourceController(which any good DI container should provide in their error messages).In AutoFac, activating a request scoped service outside of a request scope creates a binding to the singleton scope by default. The default DependencyInjection resolves this ambiguity the other direction, by breaking.
The correct fix is by making the whole dependency graph either not-request-scoped, or request-scoped (since making a default request scope is only an option in the more advanced DI containers it seems). Since the
ResourceControllerManageris a hosted controller in singleton scope, effectively allIManagedResourceControllerare in transitive singleton scope (which includesIEventQueue). So either theResourceControllerManagerhas to create a fake request scope that’s bound in transitive singleton scope, orIEventQueueshould be transitive/singleton scope.