.NETIOCMVC

Ninject dependency injection in MVC5 with WebApi

Last I was creating a new project. I wanted to use ninject as my IOC container.
This was the first time I created a new project in MVC5 with Ninject.

I struggled a little bit with configuring my Ninject IOC. It was always giving me weird errors. And that’s the reason I created this little tutorial about how you can get an MVC5 project combined with WebApi to work with a Ninject IOC.

First of all, lets create a new project. I choose not to check the WebApi, I will configure this myself later in the tutorial.

Startup project

For demo purposes I created a simple service project with an interface and a class (TestService) with the method “GetGeneralUrl” that will return the url of my blog.

The project structure looks like this:

Project created

Now lets create a WebApi controller. This you can do by right clicking the controller folder, choose to add a new controller and take the template for WebApiController.

The code of my TestServiceController looks like this:

public class TestServiceController : ApiController
{
    public string Get()
    {
        return "testUrl";
    }
}

Now first lets make the Api controllers work. You will see that there is automatically a WebApiConfig file created.

I deleted that file and added an api routing path to my RouteConfig.
De code for my defaultApi is:

GlobalConfiguration.Configuration.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = System.Web.Http.RouteParameter.Optional }
);

!Remark: Make sure that this route is above your default route. Otherwise it will not work.

You can test this configuration by running and browse to your Api.
An example: If your controllers name is TestServiceController then you need to browse to ~/api/TestService

This will give you a json file with the result you returned in your api Get method.

When this works we can start adding the Ninject part.

First add the Ninject Nuget Package:
Ninject.MVC5

After adding this package you will see there is a file added to your App_Start folder called “NinjectWebCommon.cs”
This file will register all classes specified, but this class will not be able to push your dependencies in your api controllers.

To get this to work you need to create a custom DependencyResolver and Scope.

The code of the scope class is below:

public 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;
    }
}

The code of the custom NinjectResolver is below:

public class NinjectResolver : NinjectScope, IDependencyResolver
{
    private IKernel _kernel;
    public NinjectResolver(IKernel kernel)
        : base(kernel)
    {
        _kernel = kernel;
    }
    public IDependencyScope BeginScope()
    {
        return new NinjectScope(_kernel.BeginBlock());
    }
}

After adding these classes you only need to do two more things.
1) Register the new dependencyResolver
2) Set the scanner to resolve your interfaces

Registering your new dependencyResolver is pretty straightforward.
You just need to add this line to your NinjectWebCommon:

GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);

You can put this code just after the RegisterServices(kernel) method.

The second thing was the service registration. You can do this by simple adding the ITestService registration to the RegisterServices method. The code you need to paste there is below:

kernel.Bind().To<TestService>().InRequestScope();

Now we can change our ApiController to make use of the service. The code of the Controller will now look like this:

public class TestServiceController : ApiController
{
    private readonly ITestService _testService;

    public TestServiceController(ITestService testService)
    {
        _testService = testService;
    }

    public string Get()
    {
        return _testService.GetGeneralUrl();
    }
}

When we run our application and browse to the webApi url (in my case ~/api/TestService), I get the json with the message created in the TestService.

The full working example can be downloaded here:



5 thoughts on “Ninject dependency injection in MVC5 with WebApi

  1. I got following error.

    Error activating string using conditional implicit self-binding of string
    Provider returned null.
    Activation path:
    4) Injection of dependency string into parameter connectionString of constructor of type ApplicationAreaRepository
    3) Injection of dependency IApplicationAreaRepository into parameter areaRepository of constructor of type AreaApplicationService
    2) Injection of dependency IAreaApplicationService into parameter areaApplicationService of constructor of type ApplicationAreaController
    1) Request for ApplicationAreaController

    Suggestions:
    1) Ensure that the provider handles creation requests properly.

    please help me to resolved this

  2. I have been trawling the internet for ages for this solution. I have even resorted to not using an IOC and injecting manually.

    Thank you so much for this.

    Cheers

    John

Leave a Reply

Your email address will not be published. Required fields are marked *