MVC4 / Ninject - How to change bindings after Authentication - asp.net-mvc-4

I am using MVC4 with Ninject (4.0.30319) and NinjectWebCommon.cs. I have Ninject set up and working with a common set of bindings for MVC and the WebAPI.
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
// Install our Ninject-based IDependencyResolver into the Web API config
GlobalConfiguration.Configuration.DependencyResolver = new NinjectWebAPIDependencyResolver(kernel);
// Install our Ninject-based IDependencyResolver into the MVC config
DependencyResolver.SetResolver(new NinjectMVCDependencyResolver(kernel));
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<DBDataContext>().To<DBDataContext>();
kernel.Bind<IChecksRepository>().To<ChecksRepository>();
kernel.Bind<IDepartmentsRepository>().To<DepartmentsRepository>();
kernel.Bind<IEmployeesRepository>().To<EmployeesRepository>();
kernel.Bind<IScheduleRepository>().To<ScheduleRepository>();
kernel.Bind<IVacanciesRepository>().To<VacanciesRepository>();
kernel.Bind<IVacancyTypes>().To<VacancyTypesRepository>();
}
public static void RegisterAuthenticatedServices()
{
bootstrapper.Kernel.Bind<DBDataContext>().To<DBDataContext>().WithPropertyValue("ChangedByPKID", Globals.UserPKID);
}
In Global.asax I have some one-shot code to determine when the user is authenticated and it calls RegisterAuthenticatedServices to change the binding and it executes without an exception. The problem is that after the binding is changed and a controller is requested MVC complains that "No parameterless constructor defined for this object" which I am guessing means the DBDataContext binding is trashed in Ninject. Not sure what I am doing wrong.

Unbind the context and then bind it back with the changes:
public static void RegisterAuthenticatedServices()
{
bootstrapper.Kernel.Unbind<DBDataContext>();
bootstrapper.Kernel.Bind<DBDataContext>().To<DBDataContext>().WithPropertyValue("ChangedByPKID", Globals.UserPKID);
}

Related

LightInject IoC container throws stackoverflow in fallback method

I am fiddling with LightInject to try and set up a IoC solution containing a Domain proj, a Infrastructure proj, a MVC proj, and a DependencyResolution proj. Infrastructure, MVC, and DependencyResolution references Domain. MVC references DependencyResolution and DependencyResolution references LightInject.
The idea is that DependencyResolution registers all necessary dependencies at app startup. It has no knowledge of the controllers in the MVC proj at this time. Instead I set up a fallback routine to catch all unknown MVC Controller classes. In the fallback routine I then register the MVC Controller and return it. By doing this I expect this code to only be run one time, since it is only by the first hit the MVC Controller is not registered yet. But this is not the case. Instead I get a StackOverflowException because the fallback routine is hit every time the MVC Controller is asked for even though it was registered the first time.
So the question is why this happens? Is this expected behaviour and if so, why is that and how to get around it?
Edit: Here is the source code below.
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(DependencyResolution.App_Start.WebCommon), "Start")]
namespace DependencyResolution.App_Start
{
static class WebCommon
{
private static readonly TempProject.LightInject.ServiceContainer _serviceContainer = new TempProject.LightInject.ServiceContainer();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
var container = _serviceContainer;
RegisterServices(container);
Domain.ServiceLocator.SetServiceLocator(() => new ServiceLocator(container));
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="container">The IoC container.</param>
private static void RegisterServices(TempProject.LightInject.ServiceContainer container)
{
System.Func<TempProject.LightInject.ServiceRequest, object> fallback = request =>
{
var serviceType = request.ServiceType;
container.Register(serviceType, serviceType);
return container.GetInstance(serviceType);
};
container.RegisterFallback((type, s) => type.Name.EndsWith("Controller"), request => fallback(request));
var assembly = typeof(Domain.IServiceLocator).Assembly;
container.RegisterAssembly(assembly);
}
}
}
The RegisterFallback method expects a factory as the second parameter and does not seem to register the type in such a way that the container can resolve it.
Your factory needs to new up the instance and pass it back.
Func<ServiceRequest, object> fallback = request =>
{
if (request.ServiceType == typeof(XYZController))
{
return new XYZController(container.GetInstance<IDependency>());
}
else
{
throw new InvalidOperationException(request.ServiceType.FullName);
}
};
This might be an issue worth raising with the developers.
You could load the MVC assemblies using code something like this:
private IEnumerable<Assembly> LoadAssemblies(string folder)
{
var dlls =
from file in new DirectoryInfo(folder).GetFiles()
where file.Extension == ".dll"
select file.FullName;
var assemblies = new List<Assembly>();
foreach (string dll in dlls) {
try {
assemblies.Add(Assembly.LoadFile(dll));
}
catch { }
}
return assemblies;
}
And register all the controllers with the LightInject MVC Integration Package

Why do I get an Ninject InvalidOperation exception after my API Controller has completed its request?

I have an MVC4 web app project as part of a larger solution. I also have a test project. I am working with a bunch of code that is not going to be reworked, so I can't always make the changes I would like to make.
The MVC4 web app has "normal" Controllers, and Web API Controllers. We are using the RTM version of the Web API, and not an RC.
I attempted to introduce IoC into the project. Using the NuGet installation technique (as opposed to downloading the DLLs and referencing them directly), I installed:
Ninject v3.0.1.10,
Ninject.MVC3 v3.0.0.6
Ninject.Extensions.Factory v3.0.1.0
Ninject.Web.Common v 3.0.0.7
I have no other referenced component in my solution that makes use of Ninject.
Then, following the advice given by Brad Wilson, and his Github Gist https://gist.github.com/2417226, and similar advice given by Filip W here http://www.strathweb.com/2012/05/using-ninject-with-the-latest-asp-net-web-api-source/, I have implemented a NinjectResolver, and "registered" in with the global configuration.
When I fire up the web app, the default page maps to an Index action on the ProjectController. This renders a view, which uses Knockout to populate a ViewModel via a call to an ApiController action called ApiProjectController.Get().
My NinjectWebCommon.cs code looks like this:
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Web.Http;
using System.Web.Http.Dependencies;
using Ninject.Extensions.Factory;
using Ninject.Syntax;
using OfficeWebApp.Utilities;
[assembly: WebActivator.PreApplicationStartMethod(typeof(OfficeWebApp.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(OfficeWebApp.App_Start.NinjectWebCommon), "Stop")]
namespace OfficeWebApp.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
public static class NinjectWebCommon
{
private static readonly Bootstrapper Bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
Bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
Bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IDataManagerConnection>().To<DataManagerConnection>().WithConstructorArgument("overriddenConnectionString", string.Empty);
kernel.Bind<IDataManagerConnectionFactory>().ToFactory();
}
}
public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;
internal NinjectDependencyScope(IResolutionRoot resolver)
{
Contract.Assert(resolver != null);
this.resolver = resolver;
}
public void Dispose()
{
IDisposable disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}
public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.GetAll(serviceType);
}
}
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}
}
The ProjectController code is:
public class ProjectController : Controller
{
private readonly IDataManagerConnectionFactory _dataManagerConnectionFactory;
public ProjectController(IDataManagerConnectionFactory dataManagerConnectionFactory)
{
_dataManagerConnectionFactory = dataManagerConnectionFactory;
}
[HttpGet]
public ActionResult Index()
{
//TODO:
ViewBag.Organisation = "Preview";
return View();
}
}
... and the ApiProjectController:
public class ApiProjectController : ApiController
{
private readonly IDataManagerConnectionFactory _dataManagerConnectionFactory;
public ProjectsController(IDataManagerConnectionFactory dataManagerConnectionFactory)
{
_dataManagerConnectionFactory = dataManagerConnectionFactory;
}
[HttpGet]
public IEnumerable<ProjectTileModel> Get()
{
using (IDataManagerConnection connection = _dataManagerConnectionFactory.Create())
{
List<ProjectTileModel> projectViewModels = connection.DataManager.GetProjectInfos()
.ToList();
return projectViewModels;
}
}
}
After the ApiProjectController.Get() action method has comepleted, Ninject throws the following exception at me:
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.
The call stack looks like this:
Ninject.dll!Ninject.Components.ComponentContainer.Get(System.Type component) Line 160 C#
Ninject.dll!Ninject.Components.ComponentContainer.Get<Ninject.Activation.Caching.ICache>() Line 116 + 0x46 bytes C#
Ninject.Web.Common.dll!Ninject.Web.Common.OnePerRequestHttpModule.DeactivateInstancesForCurrentHttpRequest.AnonymousMethod__1(Ninject.IKernel kernel) Line 74 + 0x27 bytes C#
Ninject.dll!Ninject.GlobalKernelRegistration.MapKernels(System.Action<Ninject.IKernel> action) Line 75 + 0xe bytes C#
Ninject.Web.Common.dll!Ninject.Web.Common.OnePerRequestHttpModule.DeactivateInstancesForCurrentHttpRequest() Line 76 C#
Ninject.Web.Common.dll!Ninject.Web.Common.OnePerRequestHttpModule.Init.AnonymousMethod__0(object o, System.EventArgs e) Line 56 + 0x9 bytes C#
This exception is being thrown in the following piece of Ninject code, in the ComponentContainer.cs file:
Type implementation = _mappings[component].FirstOrDefault(); // <-- see note below...
if (implementation == null)
throw new InvalidOperationException(ExceptionFormatter.NoSuchComponentRegistered(component)); // <-- exception thrown here
Note: at the line indicated above, the _mappings collection contains exactly one item; the key matches the Type we are looking for (ICache), but the Values member (which is a List<Type>) is empty (0 count)
Should I not be using the OnePerRequestHttpModule? Is there something funny happening because I'm using .ToFactory() in my bindings? I don't really know why the OnePerRequestHttpModule is calling DeactivateInstancesForCurrentHttpRequest() but then Ninject seems to be wanting to get at it's internal cache (maybe??)
What is it that I am doing wrong?
I never really got to the bottom of this. I don't know if it is a bug in Ninject, or whether I was simply using it incorrectly. I have, however, worked around my problem by switching IoC Containers to AutoFAC.

Ninject not working in Web API contructor in ASP.NET MVC 4

I am new to ASP.NET Web API.
I have upgraded my ASP.NET MVC 3 project to ASP.NET MVC 4 by using this tutorial.
Now I am trying to use Web Api here, as you can see I am trying to use ninject here, but when I declare ProductsController constructor in such a way, this does not work.
public class ProductsController : ApiController
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
this._productService = productService;
}
public List<Product> GetProducts()
{
return _productService.GetAllProducts();
}
}
Please help me on this.
If I add this constructor there is no call made to Web Api methods, I confirmed this by using breakpoints and it makes call otherwise.
Browser shows an xml error which reads
<Error><Message>An error has occurred.</Message></Error>
My NinjectWebCommon.cs class code is
[assembly: WebActivator.PreApplicationStartMethod(typeof(Web.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(Web.App_Start.NinjectWebCommon), "Stop")]
namespace Web.App_Start
{
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IProductService>().To<ProductService>();
}
}
}
You can follow these steps to get WebApi and Ninject up and running:
1 Create a new WebApi project
2 Add the following code for a field and a constructor to the default ValuesController:
private IFooService _foo;
public ValuesController(IFooService foo)
{
_foo = foo;
}
3 Create an interface IFooService and a class FooService
public interface IFooService
{
}
public class FooService : IFooService
{
}
4 Run the following command in your Nuget Packag Manager Console to install Ninject
Install-Package Ninject.MVC3
5 Add the following binding to App_Start\NinjectWebCommon.cs in method RegisterServices(IKernel kernel)
kernel.Bind<IFooService>().To<FooService>().InRequestScope();
In your code, you are probably not calling the NInject configuration at the right moment. When you use the Nuget package you get the following lines at the top of your Ninject file:
[assembly: WebActivator.PreApplicationStartMethod(typeof(WebApiNinjectTest.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(WebApiNinjectTest.App_Start.NinjectWebCommon), "Stop")]
These lines will make sure your code is executed at the right time.
Update : A super awesome explanation at : http://www.strathweb.com/2012/05/using-ninject-with-the-latest-asp-net-web-api-source/, Now I no longer have to use ProductsController(): this(new ProductService()).
Ah alas got this working now :)
Here is what I did...
I have two constructor of each of my WebApiController. For example for my ProductsController now the constructor I needed to define were as follows...
public class ProductsController : ApiController
{
private readonly IProductService _productService;
public ProductsController(): this(new ProductService())
{
}
public ProductsController(IFolderService productService)
{
this._polderService = productService;
}
public List<Product> GetProducts()
{
return _productService.GetAllProducts();
}
}
:)

SignalR Dependency Resolver not working from Javascript Hubs

I've recently upgraded to the new version of the excellent SignalR library, and moved all my Dependency Injection from StructureMap to Ninject, as Ninject seemed to be better supported.
I've got the dependency injection working fine for Server-side notifications using the "Broadcasting over a Hub from outside of a Hub" described here: https://github.com/SignalR/SignalR/wiki/Hubs.
The problem I'm getting is that all SignalR messages originating from the Javascript hub don't seem to be triggering the dependency injection.
I'm also using MVC4 WebAPI which also takes some shoe-horning to get dependency injection working.
Here's my Hub:
public class PresenceHub : Hub, IPresenceHub
{
private readonly IUserRepository _userRepository;
private readonly IFormsAuthenticationProvider _formsAuthenticationProvider;
public PresenceHub(IFormsAuthenticationProvider formsAuthenticationProvider, IUserRepository userRepository)
{
_userRepository = userRepository;
_formsAuthenticationProvider = formsAuthenticationProvider;
}
public void PresenceChange(string presence)
{
var user = _userRepository.FindById(_formsAuthenticationProvider.GetUserId());
var rosterEntry = Mapper.Map<User, RosterEntryDto>(user);
rosterEntry.Presence = presence;
Clients.updatePresence(rosterEntry);
}
}
Here's my Ninject Bootstrapper:
Namespace SLx.Web.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
public static void Stop()
{
bootstrapper.ShutDown();
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
// SignalR Ninject Resolver
GlobalHost.DependencyResolver = new SignalR.Ninject.NinjectDependencyResolver(kernel);
// WebApi Ninject Resolver
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
}
}
I'm notifying clients on the serverside via a PresenceProxy defined as follows:
public class PresenceHubProxy : IPresenceHubProxy
{
private readonly IHubContext _hubContext;
public PresenceHubProxy()
{
_hubContext = GlobalHost.ConnectionManager.GetHubContext<PresenceHub>();
}
public void NotifyLogin(RosterEntryDto user)
{
_hubContext.Clients.updatePresence(user);
}
public void NotifyLogout(RosterEntryDto user)
{
_hubContext.Clients.updatePresence(user);
}
}
The Proxy works fine, injected into Controllers or their dependencies, and can send messages to the clients.
When the clients try to call SignalR via Javascript I get the following error:
No parameterless constructor defined for this object.
It looks like Ninject is not being invoked because the dependencies are not being injected into the constructor. What do I need to do to get Dependency Injection working for Javascript calls too?
Update --
Following advice from DFowler, I've replaced the Resolver in PostApplicationStart. Debugging I can see in the Immediate Window that SignalR.GlobalHost.Resolver is of type NinjectDependencyResolver but its still not working I get the same error - no paramaterless constructor.
I've then removed the NinjectDependencyResolver NuGet Library and added the source file to my solution and am using that for debugging purposes. Debugging on GetService and GetServices shows that neither method is ever called in NinjectDependencyResolver.
Any Ideas?
Problem was I hadn't called RouteTable.Routes.MapHubs:
GlobalHost.DependencyResolver = new SignalRNinjectResolver(NinjectWebCommon.Kernel);
RouteTable.Routes.MapHubs(new SignalRNinjectResolver(NinjectWebCommon.Kernel));
From the docs https://github.com/SignalR/SignalR/wiki/Extensibility:
NOTE: DO NOT override the global resolver in PreApplicationStart, it will not work, or it'll work only sometimes. Do it in PostApplicationStart (using WebActivator) or in Global.asax.

NinjectWebCommon Bindings in RegisterServices not working for me in WebApi

I create a new ASP.NET Web API project. I then use nuget to pull Ninject.Web.Common, then I download and build Ninject.Web.WebApi from here. Included it in the project. I added a service and the injection via constructor, setup binding (the debugger shows that the code actually hits the bind) but still throws this error:
Error activating IValueService
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IValueService into parameter valueService of constructor of type ValuesController
1) Request for ValuesController
Suggestions:
1) Ensure that you have defined a binding for IValueService.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.
Libraries in my project:
Ninject.dll
Ninject.Web.Common
Ninject.Web.Webapi
WebActivator
All ninject libraries are marked as version 3.
Here is the Code:
[assembly: WebActivator.PreApplicationStartMethod(typeof(MvcApplication3.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(MvcApplication3.App_Start.NinjectWebCommon), "Stop")]
namespace MvcApplication3.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IValueService>().To<ValueService>();
}
}
}
service:
public interface IValueService
{
List<string> GetStrings();
}
public class ValueService : IValueService
{
public List<string> GetStrings()
{
return new List<string>{"test", "test"};
}
}
controller:
public class ValuesController : ApiController
{
private readonly IValueService valueService;
// GET /api/values
public ValuesController(IValueService valueService)
{
this.valueService = valueService;
}
}
The downloaded project sample from github works but not when I create a new project. Am I missing a step?
I just checked that there is no issue with this extension (at least not with the lastest MVC4 preview):
Create a new MVC4 WEB Api project
Nuget Install-Package Ninject.Web.WebAPI
Change controller + add bindings
Your code looks good. There must be a problem somewhere else.
Do not bind directly in RegisterServices but first create a class from
IDependencyResolver en add your bindings in AddBindings
example
See in book Pro ASP.NET MVC5 from Adam Freeman