-
-
Save odytrice/5842010 to your computer and use it in GitHub Desktop.
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>(); | |
} | |
} | |
} |
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.
@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.
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 WebActivator
s and GlobalConfiguration
which was causing issues when OWIN authentication conflicted with the forms app authentication.
Great stuff odytrice, thanks for posting this