Dependency Injection .NET Core - InvalidOperationException
Solution 1
public LoginService(LoginHttpService loginHttpService, IOptions<UrlConfigurations> urlConfigurations)
{
_loginHttpService = loginHttpService;
_urlConfigurations = urlConfigurations.Value;
}
Change LoginHttpService
in LoginService
class constructor to interface ILoginHttpService
.
This should work.
Solution 2
In my case, I forget of add context service in Startup.cs
:
services.AddDbContext<My_ScaffoldingContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MyConnectionString")));
nick gowdy
Updated on September 06, 2021Comments
-
nick gowdy about 2 years
I'm learning .NET Core, and I'm trying to use
IServiceCollection
in the startup.cs to resolve my dependencies. I'm injecting a depdency in my controller, and that depency is resolved to a class which also has an injected dependency. Basically I'm getting anInvalidOperationException
because it's unable to activate the dependency.This is my stacktrace:
InvalidOperationException: Unable to resolve service for type 'TestApplication.Services.LoginHttpService' while attempting to activate 'TestApplication.Services.LoginService'. Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet<Type> callSiteChain, ParameterInfo[] parameters, bool throwIfCallSiteNotFound) Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet<Type> callSiteChain, ParameterInfo[] parameters, bool throwIfCallSiteNotFound) Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.CreateCallSite(ServiceProvider provider, ISet<Type> callSiteChain) Microsoft.Extensions.DependencyInjection.ServiceProvider.GetResolveCallSite(IService service, ISet<Type> callSiteChain) Microsoft.Extensions.DependencyInjection.ServiceProvider.GetServiceCallSite(Type serviceType, ISet<Type> callSiteChain) Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType, ServiceProvider serviceProvider) System.Collections.Concurrent.ConcurrentDictionaryExtensions.GetOrAdd<TKey, TValue, TArg>(ConcurrentDictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TArg, TValue> valueFactory, TArg arg) Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired) lambda_method(Closure , IServiceProvider , Object[] ) Microsoft.AspNetCore.Mvc.Internal.TypeActivatorCache.CreateInstance<TInstance>(IServiceProvider serviceProvider, Type implementationType) Microsoft.AspNetCore.Mvc.Controllers.DefaultControllerFactory.CreateController(ControllerContext context) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeNextResourceFilter>d__22.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeAsync>d__20.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__18.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__18.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.VisualStudio.Web.BrowserLink.BrowserLinkMiddleware+<ExecuteWithFilter>d__7.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()
My startup class with registered dependencies:
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); // Added - uses IOptions<T> for your settings. services.AddOptions(); // Added - Confirms that we have a home for our DemoSettings services.Configure<UrlConfigurations>(Configuration.GetSection("UrlConfigurations")); //services.AddSingleton<ITokenProvider, Tokenpro>(); services.AddTransient<ILoginService, LoginService>(); services.AddSingleton<IHttpService, HttpService>(); services.AddSingleton<ILoginHttpService, LoginHttpService>(); services.AddSingleton<IUrlConfigurations, UrlConfigurations>(); services.AddSingleton<IJsonDeserializer, JsonDeserializer>(); services.AddSingleton<IHttpClientFactory, HttpClientFactory>(); services.AddSingleton<IJsonValidator, JsonValidator>(); }
I'm going to change the scope (transient, singleton, etc.) to be the correct type as well once the runtime error is resolved.
My login controller:
using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using TestApplication.Configurations; using TestApplication.Interfaces.Configurations; using TestApplication.Interfaces.Services; using TestApplication.Models; // For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace TestApplication.Controllers { public class LoginController : Controller { private readonly ILoginService _loginService; private readonly IUrlConfigurations _urlConfigurations; public LoginController(ILoginService loginService, IOptions<UrlConfigurations> urlConfigurations) { _loginService = loginService; _urlConfigurations = urlConfigurations.Value; } public async Task<IActionResult> Index() { var jsonWebToken = await GetJsonWebToken(); return View(); } private async Task<JwtSecurityToken> GetJsonWebToken() { // get token - hard-coded for now var login = new LoginViewModel { Username = "[email protected]", Password = "marshwall" }; var jsonWebToken = await _loginService.Login(login); return jsonWebToken; } } }
My login service which uses
LoginHttpService
:using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Options; using Newtonsoft.Json; using TestApplication.Configurations; using TestApplication.Interfaces.Configurations; using TestApplication.Interfaces.Services; using TestApplication.Models; namespace TestApplication.Services { public class LoginService : ILoginService { private readonly LoginHttpService _loginHttpService; private readonly IUrlConfigurations _urlConfigurations; public LoginService(LoginHttpService loginHttpService, IOptions<UrlConfigurations> urlConfigurations) { _loginHttpService = loginHttpService; _urlConfigurations = urlConfigurations.Value; } public async Task<JwtSecurityToken> Login(LoginViewModel login) { login.LoginMapper(); var response = await _loginHttpService.PostLoginAsync(_urlConfigurations.GetToken, login.EncodedLoginDetailsContent); if (response == null) return null; var data = await response.Content.ReadAsStringAsync(); // Deserialize JWT var accessToken = JsonConvert.DeserializeObject<UserResponseModel>(data)?.access_token; if (string.IsNullOrEmpty(accessToken) || !response.IsSuccessStatusCode) return null; // Cast JWT to correct class var securityToken = new JwtSecurityTokenHandler().ReadToken(accessToken) as JwtSecurityToken; return securityToken; } } }
Does anyone know what I've done wrong in my startup.cs class? I want to resolve
TestApplication.Services.LoginHttpService
which is used inTestApplication.Services.LoginService
.