0

I'm struggling with enabling Ninject's constructor injection in a Web Service application. Here's the steps I took (Visual Studio 2013):

1) Created a new project with "ASP.NET Web Application" template.

2) Selected an "Empty" application template in the second step of the project creation wizard.

3) In the third step called "Add folders and core references for" selected "Web API"

4) The project is created, now I added a controller of type "Web API 2 Controller - Empty". Added the following code:

using System.Web.Http;

namespace WebApplication1.Controllers
{
    public interface IDummy
    {
    }

    public class Dummy : IDummy
    {
    }

    public class DefaultController : ApiController
    {
        public DefaultController(IDummy dummy)
        {
        }

        [HttpGet]
        [Route("")]
        public string Index()
        {
            return "Hello World!";
        }
    }
}

5) Installed NuGet package: Ninject.Web.WebApi (Ninject integration for WebApi2), now I've found in other threads that to make it work with IIS I need to install Ninject.Web.Common.WebHost package. After this, the NinjectWebCommon.cs file appeared in AppStart. The only edit I did for this file was in RegisterServices method:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<IDummy>().To<Dummy>();
}

Now when I try to run the application (locally, just pressing F5 in Visual Studio) I would expect to get the Hello World string in a browser, but instead I get the infamous parameterless constructor error: Error which means that the Ninject is for some reason not doing its job I guess. Unfortunately googling for solution was fruitless so far. Anyone can hint me what should I do to make this work? Thanks in advance.

Piotr
  • 572
  • 5
  • 22
  • Do you have `WebActivatorEx` installed? – Ben Robinson Aug 13 '15 at 08:48
  • Yup, the Ninject.Web.Common.WebHost package depends on it. – Piotr Aug 13 '15 at 08:51
  • Do you have https://www.nuget.org/packages/Ninject.MVC3/ installed? Think you'll need it so Ninject knows to hook up the controllers – PeteG Aug 13 '15 at 08:52
  • I tried adding it. Now the app throws an FileNotFoundException in NinjectWebCommon.CreateKernel() "Could not load file or assembly 'System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified." Please note that I did not select the MVC template when creating the project (it is not a web page, and will not have any views). – Piotr Aug 13 '15 at 09:04

1 Answers1

0

I was able to get this working quite simply by using this solution. You only need to install Ninject.Web.WebApi and then add the following code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Dependencies;
using Ninject;
using Ninject.Activation;
using Ninject.Parameters;
using Ninject.Syntax;

internal class NinjectDependencyResolver : NinjectScope, IDependencyResolver
{
    private readonly IKernel kernel;

    public NinjectDependencyResolver(IKernel kernel)
        : base(kernel)
    {
        if (kernel == null)
            throw new ArgumentNullException("kernel");

        this.kernel = kernel;
    }

    public IDependencyScope BeginScope()
    {
        return new NinjectScope(this.kernel.BeginBlock());
    }
}

internal class NinjectScope : IDependencyScope
{
    protected IResolutionRoot resolutionRoot;
    public NinjectScope(IResolutionRoot kernel)
    {
        resolutionRoot = kernel;
    }
    public object GetService(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).SingleOrDefault();
    }
    public IEnumerable<object> GetServices(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).ToList();
    }
    public void Dispose()
    {
        IDisposable disposable = (IDisposable)resolutionRoot;
        if (disposable != null) disposable.Dispose();
        resolutionRoot = null;
    }
}

Usage

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        IKernel kernel = new StandardKernel();

        kernel.Bind<IDummy>().To<Dummy>();

        config.DependencyResolver = new NinjectDependencyResolver(kernel);

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}
Community
  • 1
  • 1
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • Works, also as you pointed out but I will underline this, now I don't need the Ninject.Web.Common.WebHost package :). Thanks. – Piotr Aug 14 '15 at 09:34
  • Thank you for making step by step instructions for setting up the scenario. It made answering your question a breeze. – NightOwl888 Aug 14 '15 at 09:49