i have setup my project with Ninject IoC
.
My project has regular Asp.Net MVC
controllers and Web Api
controllers. Now, Ninject
works with Web Api
but Ninject
doesn't work with regular Asp.MVC
controllers.
My regular MVC controller implementation;
public class GalleryController : BaseController { public GalleryController(IUow uow) { Uow = uow; } ........ }
Error when using with regular controller
An error occurred when trying to create a controller of type 'Web.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.]
However, when i try the same code with Web Api, it works
public class GalleryController : BaseApiController { public GalleryController(IUow uow) { Uow = uow; } ...... }
my interface which holds difference repositories (the factory pattern)
public interface IUow { // Save pending changes to the data store. void Commit(); //Repositoryries IRepository<Gallery> Gallery { get; } IMenuRepository Menus { get; } }
NinjectDependencyScope
class;
public class NinjectDependencyScope : IDependencyScope { private IResolutionRoot resolver; internal NinjectDependencyScope(IResolutionRoot resolver) { Contract.Assert(resolver != null); this.resolver = resolver; } public void Dispose() { var 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); } }
NinjectDependencyResolver
class;
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()); } }
Ninject
configuration for Global.asax;
public class IocConfig { public static void RegisterIoc(HttpConfiguration config) { var kernel = new StandardKernel(); // Ninject IoC //kernel.Load(Assembly.GetExecutingAssembly()); //only required for asp.net mvc (not for webapi) // These registrations are "per instance request". // See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/ kernel.Bind<RepositoryFactories>().To<RepositoryFactories>() .InSingletonScope(); kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>(); kernel.Bind<IUow>().To<Uow>(); // Tell WebApi how to use our Ninject IoC config.DependencyResolver = new NinjectDependencyResolver(kernel); } }
Global.asax
protected void Application_Start() { // Tell WebApi to use our custom Ioc (Ninject) IocConfig.RegisterIoc(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); GlobalConfig.CustomizeConfig(GlobalConfiguration.Configuration); AreaRegistration.RegisterAllAreas(); }
It helps you split your application into a collection of loosely-coupled, highly-cohesive pieces, and then glue them back together in a flexible manner. By using Ninject to support your software's architecture, your code will become easier to write, reuse, test and modify.
Ninject is and will always be free for both personal and commercial projects. It's also open source, so you can fork the code and make any changes you like.
I have written some gists to help configure Ninject with MVC and Web Api. Simply include the file(s):
To add Bindings for concrete Types, Just put them in the Load()
method of the MainModule. You can create as many modules as you like to keep bindings organized. but you'll also have to add them to the array that is returned in the Modules
property.
Then Add to the Application_Start()
method
NinjectContainer.RegisterModules(NinjectModules.Modules)
(for MVC)NinjectHttpContainer.RegisterModules(NinjectHttpModules.Modules)
(for WebApi)Note that you can use the same NinjectModules.Modules
for both the MVC and WebApi registration. I just separated it for clearity
UPDATE: Remember to Remove NinjectWebCommon.cs from your project as it loads and bootstraps a new kernel at Runtime which unfortunately is only for MVC.
UPDATE: You can also use
NinjectContainer.RegisterAssembly()
(for MVC)NinjectHttpContainer.RegisterAssembly()
(for WebApi)This will scan your current assembly for all modules. This way you can put your modules anywhere in your project and it will be registered
With MVC 5 and Web API 2.2 I solved this problem by making sure I included the following NuGet packages:
Ninject.MVC5
Ninject.Web.WebApi.WebHost
for Web APIThis installed other Ninject dependencies and allowed me to RegisterServices
through NinjectWebCommon.cs
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With