0

im injecting with ninject a concrete type in the controller constructor like so.

  public class HomeController : BaseController
    {
        IUserService userService;
        public HomeController(IUserService _userService)
        {
           this.userService = _userService;
        }
}

then in ninject im registering like so.

kernel.Bind<IUserService>().To<UsersService>();

However my UsersService has a constructor which takes the username of the currently logged in user.

how do i register in ninject for my concrete type to be passed in the constructor the httpcontext...User.Identity.Name?

Aflred
  • 4,435
  • 6
  • 30
  • 43

1 Answers1

1

You can use the Ninject Factory Extensions - effectively what you'd be doing is injecting an abstract factory that creates IUserService at runtime instead of an actual IUserService.

Note that this isn't the dreaded "Service Locator" anti-pattern because the factory will only produce IUSerService instances

public class HomeController : BaseController
{
    IUserServiceFactory userServiceFactory;

    public HomeController(IUserServiceFactory _userServiceFactory)
    {
        this.userServiceFactory= _userServiceFactory;
    }

    public ActionResult SomeAction()
    {
       //whatever code to get your current userID here, and then:
       var userService = _userServiceFactory.Create(userID);
       //now use userService as required.
       var result = userService.DoMagicStuff();
    }
}

However, just to point one thing out - if this is a service, then to me it sounds more reasonable to have the current userID, etc, as an argument to the service's methods, as opposed to an invariant of the actual service itself. Services should where possible be stateless...

As a general rule of thumb, runtime data isn't a good candidate as a service dependency - there are exceptions, of course.

Stephen Byrne
  • 7,400
  • 1
  • 31
  • 51