Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.IUrlHelper' while attempting to activate

I am trying to separate code from controller to service that I created. What I did is to create a User Service with interface IUserService.

Moved RegisterUser code from directly controller to UserService, the next challenge I get was that Url which works directly with Controller doesn't work with Service.

This code from Controller to Service has been changed like this:

if in Controller

var callbackUrl = Url.EmailConfirmationLink(user.Email, token, model.contactno, Request.Scheme);

Changed from Controller to Service:

  private IUrlHelper _urlHelper;

    public UserService (IUrlHelper urlHelper, HttpRequest request) {
_urlHelper = urlHelper;
}

this was constructor,

in Method I am calling it like this:

        var callbackUrl = _urlHelper.EmailConfirmationLink (user.Email, token, U.Email, _request.Scheme);

I mentioned in DI in Startup.cs like this:

services.AddScoped<IUserService, UserService>();

There is no Excpetion at compile time. At run time it is throwing below excption:

Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.IUrlHelper' while attempting to activate 'erp.Services.UserService'.

Not very clear what exactly has to be done.

here is full stack trace to see the error more closely. well I can't say the exact line as I am not debugging but just copying from the logs:

Executed endpoint 'erp.Controllers.AccountController.Register (erp)'
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Http.HttpRequest' while attempting to activate 'erp.Services.UserService'.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
   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)
like image 390
Jay Avatar asked Feb 23 '19 07:02

Jay


Video Answer


1 Answers

For Object reference not set to an instance of an object, it is caused by that you did not register IActionContextAccessor.

Try follow steps below:

  1. UserService

    public interface IUserService
    {
        void RegisterUser();
    }
    public class UserService : IUserService
    {
        private IUrlHelper _urlHelper;
        private HttpRequest _request;
    
        public UserService(IUrlHelper urlHelper, IHttpContextAccessor httpContextAccessor)
        {
            _urlHelper = urlHelper;
            _request = httpContextAccessor.HttpContext.Request;
        }
        public void RegisterUser()
        {
            var callbackUrl = _urlHelper.EmailConfirmationLink("user.Email", "token", _request.Scheme);
            //throw new NotImplementedException();
        }
    }
    
  2. Register

    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
    services.AddScoped<IUrlHelper>(x => {
        var actionContext = x.GetRequiredService<IActionContextAccessor>().ActionContext;
        var factory = x.GetRequiredService<IUrlHelperFactory>();
        return factory.GetUrlHelper(actionContext);
    });
    
    services.AddScoped<IUserService, UserService>();
    
like image 59
Edward Avatar answered Sep 28 '22 01:09

Edward