asp.net-mvc-3ninjectgeneric-handler

How do I inject into some generic asp.net http handler using Ninject?


I'm a newbie using Ninject and I can't figure out how to inject into my generic http handler. I have a MVC3 project and I'm injecting my services into controllers with no problem at all. This is what I got in my Ninject App_start class for registering services:

        private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<NLSubscriber.Core.Service.Repository.INLUserRepository>().To<NLSubscriber.Core.Service.Repository.EFDAL.EFNLUserRepository>().InRequestScope();
        kernel.Bind<Neticon.Mvc.Helpers.IConfigHelper>().To<Neticon.Mvc.Helpers.AzureEnabledConfigHelper>().InSingletonScope();
        kernel.Bind<Neticon.Security.Service.IAuthenticationService>().ToMethod(m => Neticon.Security.Service.SecurityServiceFactory.CreateAuthenticationService()).InRequestScope();
        kernel.Bind<Neticon.Security.Service.IMembershipService>().ToMethod(m => Neticon.Security.Service.SecurityServiceFactory.CreateMembershipService()).InRequestScope();
        kernel.Bind<Neticon.Security.Service.IRoleManagerService>().ToMethod(m => Neticon.Security.Service.SecurityServiceFactory.CreateRoleManagerService()).InRequestScope();

When I try to get some service from my generic handler by using property injection (with [inject] attribute) I always get null. This is how my handler looks like:

    public class SubscriberHandler : IHttpHandler
{
    [Inject]
    public INLUserRepository userRep { get; set;}

    public void ProcessRequest(HttpContext context)
    {
        var users = userRep.GetUsers(); //userRep is always null here
    }


    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

I have also tried doing it like this:

    readonly INLUserRepository userRep;

    public SubscriberHandler()
    {

        using (IKernel kernel = new StandardKernel(new App_Start.NJRepositoryModule()))
        {
            userRep = kernel.Get<INLUserRepository>();
        }
    }

but I'm getting an exception: "Error loading Ninject component ICache. No such component has been registered in the kernel's component container. Suggestions: 1) If you have created a custom subclass for KernelBase, ensure that you have properly implemented the AddComponents() method. 2) Ensure that you have not removed the component from the container via a call to RemoveAll(). 3) Ensure you have not accidentally created more than one kernel."

That's suggesting me that I'm not supposed to instantiate more than one kernel in my application, right? What am I doing wrong? Thanks


Solution

  • You could use the dependency resolver:

    public class SubscriberHandler : IHttpHandler
    {
        public INLUserRepository userRep { get; private set; }
    
        public SubscriberHandler()
        {
            userRep = DependencyResolver.Current.GetService<INLUserRepository>();
        }
    
        public void ProcessRequest(HttpContext context)
        {
            var users = userRep.GetUsers(); //userRep is always null here
        }
    
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
    

    I am expecting to get negative feedback from this answer because the service locator pattern is considered by many as an anti-pattern.

    But I am not sure whether NInject allows you to use constructor injection for HTTP handlers because they are instantiated by the ASP.NET runtime.