Search This Blog

2012-03-31

Using Ninject with ASP.NET Web API

ASP.NET Web API is a reall cool feature that makes it easy to build HTTP services, and now it is a part of MVC 4. Ninject + Ninject.MVC is also a cool IoC tool but current version doesn't really work out the box within ApiController.
public class MyApiController : ApiController
{
  [Inject]
  public IRepository<Entity> repository { get; set; }

  public IQueryable<Entity> Get()
  {
    return repository.GetAll();
  }
}
It won't inject repository and you will get null reference exception. The reason is  that ApiController rely on another IDependencyResolver interface, from System.Web.Http.Services namespace. There is a question on stackoverflow and nice article explaining how it could be done.
Basically, the idea is fairly simple: just re-implement (i.e. copy-and-paste)  NinjectDependencyResolver - the System.Web.Mvc.IDependencyResolver implementation.
public class WebApiNinjectDependencyResolver : System.Web.Http.Services.IDependencyResolver
{
  private readonly IResolutionRoot resolutionRoot;

  public WebApiNinjectDependencyResolver(IResolutionRoot resolutionRoot)
  {
    this.resolutionRoot = resolutionRoot;
  }

  public object GetService(Type serviceType)
  {
    IRequest request = this.resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
    return this.resolutionRoot.Resolve(request).SingleOrDefault();
  }

  public IEnumerable<object> GetServices(Type serviceType)
  {
    return this.resolutionRoot.GetAll(serviceType, new IParameter[0]).ToList();
  }
}
All we need to do now is register it on Application Start.
public static class NinjectWebCommon
{
  private static readonly Bootstrapper bootstrapper = new Bootstrapper();

  public static void Start()
  {
    ...
    bootstrapper.Initialize(CreateKernel);
  }

  public static void Stop()
  {
    bootstrapper.ShutDown();
  }

  private static IKernel CreateKernel()
  {
    var kernel = new StandardKernel();

    ....

    RegisterServices(kernel);
    
    // Register implementation of System.Web.Http.Services.IDependencyResolver
    GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new WebApiNinjectDependencyResolver(kernel));

    return kernel;
  }
  ...
}
That's all! Enjoy injections to your ApiControllers.

5 comments:

  1. The Ninject.Web.WebApi extension provides this functionallity. Additionally it comes with the same functionallity as Ninject.MVC3 and runs side a side with Mvc controllers so that you have to configure your service bindings only once.

    ReplyDelete