Skip to content

Instantly share code, notes, and snippets.

@odytrice
Last active February 14, 2023 12:15
Show Gist options
  • Star 33 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save odytrice/5842010 to your computer and use it in GitHub Desktop.
Save odytrice/5842010 to your computer and use it in GitHub Desktop.
A small Library to configure Ninject (A Dependency Injection Library) with a WebAPI Application.
using Ninject.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http;
using System.Web.Http.Dependencies;
// A small Library to configure Ninject (A Dependency Injection Library) with a WebAPI Application.
// To configure, take the following steps.
//
// 1. Install Packages Ninject and Ninject.Web.Common
// 2. Remove NinjectWebCommon.cs in your App_Start Directory
// 3. Add this file to your project (preferrably in the App_Start Directory)
// 4. Add Your Bindings to the Load method of MainModule.
// You can add as many additional modules to keep things organized
// simply add them to the Modules property of the NinjectModules class
// 5. Add the following Line to your Global.asax
// NinjectHttpContainer.RegisterModules(NinjectHttpModules.Modules);
// 5b.To Automatically Register all NinjectModules in the Current Project, You should instead add
// NinjectContainer.RegisterAssembly()
// You are done.
namespace Ninject.Http
{
/// <summary>
/// Resolves Dependencies Using Ninject
/// </summary>
public class NinjectHttpResolver : IDependencyResolver, IDependencyScope
{
public IKernel Kernel { get; private set; }
public NinjectHttpResolver(params NinjectModule[] modules)
{
Kernel = new StandardKernel(modules);
}
public NinjectHttpResolver(Assembly assembly)
{
Kernel = new StandardKernel();
Kernel.Load(assembly);
}
public object GetService(Type serviceType)
{
return Kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return Kernel.GetAll(serviceType);
}
public void Dispose()
{
//Do Nothing
}
public IDependencyScope BeginScope()
{
return this;
}
}
// List and Describe Necessary HttpModules
// This class is optional if you already Have NinjectMvc
public class NinjectHttpModules
{
//Return Lists of Modules in the Application
public static NinjectModule[] Modules
{
get
{
return new[] { new MainModule() };
}
}
//Main Module For Application
public class MainModule : NinjectModule
{
public override void Load()
{
//TODO: Bind to Concrete Types Here
}
}
}
/// <summary>
/// Its job is to Register Ninject Modules and Resolve Dependencies
/// </summary>
public class NinjectHttpContainer
{
private static NinjectHttpResolver _resolver;
//Register Ninject Modules
public static void RegisterModules(NinjectModule[] modules)
{
_resolver = new NinjectHttpResolver(modules);
GlobalConfiguration.Configuration.DependencyResolver = _resolver;
}
public static void RegisterAssembly()
{
_resolver = new NinjectHttpResolver(Assembly.GetExecutingAssembly());
//This is where the actual hookup to the Web API Pipeline is done.
GlobalConfiguration.Configuration.DependencyResolver = _resolver;
}
//Manually Resolve Dependencies
public static T Resolve<T>()
{
return _resolver.Kernel.Get<T>();
}
}
}
@im1dermike
Copy link

This works great. Thanks. You just need to change the Global.asax.cs line needed for this WebApi implementation to NinjectHttpContainer.RegisterModules(NinjectHttpModules.Modules). I think you copied and pasted from the MVC example.

@odytrice
Copy link
Author

I have updated it. Thanks for pointing it out

@has-taiar
Copy link

Thanks odytrice..

This was nice and helpful :)
I have got this working with the MVC one.. works great

Cheers
Has

@JohnMcNulty
Copy link

Great stuff odytrice, thanks for posting this

@tkempton
Copy link

You can actually put both the MVC and API containers and resolvers together.

You just need to make NinjectHttpResolver also implement System.Web.Mvc.IDependencyResolver and then call System.Web.Mvc.DependencyResolver.SetResolver(_resolver) in both the RegisterModules and RegisterAssembly methods (use full namespace references, not using statements as it will cause ambiguity with the System.Web.Http namespace).

This will limit it to a single Kernel without having to extract Kernel creation to a static Singleton class.

@odytrice
Copy link
Author

@tkempton That's really cool. especially if you are doing both in the same project which btw happens a lot. The only thing you might need to deal with are the namespace collisions.

@seangwright
Copy link

Thanks for this!

I already had most of these pieces in place but the configuration was not working with the setup I currently have.

In my app Web Api 2 is running on OWIN in its own IAppBuilder.Map("/api", ...); whereas the rest of the app is a large forms application/CMS that needs to communicate with the Web Api app.

I had been using WebActivators and GlobalConfiguration which was causing issues when OWIN authentication conflicted with the forms app authentication.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment