Search code examples
c#asp.netasp.net-mvcasp.net-web-apininject

Dependency Injection in ASP.NET Web API (Ninject)


I need to implement DI in my Web API Project. I'm using a Ninject and got a little problem.

This is Global.asax:

public class WebApiApplication : System.Web.HttpApplication
{
   protected void Application_Start()
   {
      NinjectModule registrations = new NinjectRegistrations();
      var kernel = new StandardKernel(registrations);
      DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));

      AreaRegistration.RegisterAllAreas();
      GlobalConfiguration.Configure(WebApiConfig.Register);
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
      RouteConfig.RegisterRoutes(RouteTable.Routes);
      BundleConfig.RegisterBundles(BundleTable.Bundles);
   }
}

This is another class for ninject:

public class NinjectRegistrations : NinjectModule
{
   public override void Load()
   {
      Bind<ICountriesRepository>().To<CountriesRepository>();
   }
}

And this code can send an Interface object to HomeController, but not to other controllers.

public class CountriesController : ApiController
{
   public ICountriesRepository db;

   // CONSTRUCTOR DO NOT RECEIVE AN INTERFACE OBJECT
   public CountriesController(ICountriesRepository a)     // CONSTRUCTOR DO NOT RECIEVE AN INTERFACE OBJECT
   {  
      db = a;
   }
}

I just need to set another controller-support, to receive an Interface object So, i will appreciate your help.


Solution

  • Your implementation is different from what you needed to inject something on the constructor.

    You need to create a DependecyResolver to inject it on the constructors. You can have something like this:

    public class NinjectRegistrations : NinjectModule
    {
        public override void Load()
        {
            Bind<IProductRepository>().To<ProductRepository>();
        }
    }
    

     public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver, System.Web.Mvc.IDependencyResolver
    {
        private readonly IKernel kernel;
    
        public NinjectDependencyResolver(IKernel kernel)
            : base(kernel)
        {
            this.kernel = kernel;
        }
    
        public IDependencyScope BeginScope()
        {
            return new NinjectDependencyScope(this.kernel.BeginBlock());
        }
    }
    

    public class NinjectDependencyScope : IDependencyScope
    {
        private IResolutionRoot resolver;
    
        internal NinjectDependencyScope(IResolutionRoot resolver)
        {
            Contract.Assert(resolver != null);
    
            this.resolver = resolver;
        }
    
        public void Dispose()
        {
            var disposable = this.resolver as IDisposable;
            if (disposable != null)
            {
                disposable.Dispose();
            }
    
            this.resolver = null;
        }
    
        public object GetService(Type serviceType)
        {
            if (this.resolver == null)
            {
                throw new ObjectDisposedException("this", "This scope has already been disposed");
            }
    
            return this.resolver.TryGet(serviceType);
        }
    
        public IEnumerable<object> GetServices(Type serviceType)
        {
            if (this.resolver == null)
            {
                throw new ObjectDisposedException("this", "This scope has already been disposed");
            }
    
            return this.resolver.GetAll(serviceType);
        }
    }
    

    On Your Global.asax

    NinjectModule registrations = new NinjectRegistrations();
    var kernel = new StandardKernel(registrations);
    var ninjectResolver = new NinjectDependencyResolver(kernel);
    
    // If you are using MVC
    DependencyResolver.SetResolver(ninjectResolver);
    
    // If you are using API
    GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver;