Later in the book it suggests that this approach can lead to duplication of code and also the risk of numerous Ninject Kernels and instructs the following instead using the DependencyResolver:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Web.Mvc;
using Ninject;
using Ninject.Syntax;
using SportsStore.Domain.Abstract;
using SportsStore.Domain.Concrete;
using SportsStore.WebUI.Infrastructure.Abstract;
using SportsStore.WebUI.Infrastructure.Concrete;
namespace SportsStore.WebUI.Infrastructure {
public class NinjectDependencyResolver : IDependencyResolver {
private IKernel kernel;
public NinjectDependencyResolver() {
kernel = new StandardKernel();
AddBindings();
}
public object GetService(Type serviceType) {
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType) {
return kernel.GetAll(serviceType);
}
public IBindingToSyntax<T> Bind<T>() {
return kernel.Bind<T>();
}
public IKernel Kernel {
get { return kernel; }
}
private void AddBindings() {
//Put additional bindings here
Bind<IProductRepository>().To<EFProductRepository>();
Bind<IAuthProvider>().To<FormsAuthProvider>();
//Create the email settings object
EmailSettings emailSettings = new EmailSettings
{
WriteAsFile = bool.Parse(ConfigurationManager.AppSettings["Email.WriteAsFile"] ?? "false")
};
Bind<IOrderProcessor>().To<EmailOrderProcessor>().WithConstructorArgument("settings", emailSettings);
}
}
}
You can find several blog on this topic and it is not possible to sum it up in few lines. But I will try to make it simple.
The way MVC2's DefaultControllerFactory works is, it first create controller type from the controller name and then creates the instance of it by using Activator.CreateInstance.
But in MVC3 it has been greatly simplfies by providing two interfaces IControllerActivator & IDependencyResolver, now DefaultControllerFactory will call dependency resolver to resolve instance of IControllerActivator by calling GetService Method. If dependency
resolver fails to resolve the Controller Instance it will again go back to MVC2's way to create the controller instance.
Please go through the articles below it will give you in depth knowledge about it.
I have looked at the links you provided and in fact your explanation is to the point. I think at this stage I am asking a lot of questions some of which will be apparent as I move on. Anyway I feel happy to go this way with DI now!
bigredhf
Member
48 Points
81 Posts
DependencyResolver why is this preferable to DefaultControllerFactory
Jun 25, 2012 06:21 PM|LINK
Hi,
I am working my way through this book and I am getting a lot out of it as I am new to MVC.
The book uses Ninject and in the earlier stages implements it by inheriting from the DefaultControllerFactory like so:
#region Imports using System.Web.Mvc; using Ninject; using SportsStore.Domain.Abstract; using SportsStore.Domain.Concrete; using System.Configuration; using SportsStore.WebUI.Infrastructure.Abstract; using SportsStore.WebUI.Infrastructure.Concrete; #endregion namespace SportsStore.WebUI.Infrastructure { /// <summary> /// Ninjects instance of the Controller factory class /// </summary> public class NinjectControllerFactory : DefaultControllerFactory { public NinjectControllerFactory() { ninjectKernel = new StandardKernel(); AddBindings(); } #region Declarations private IKernel ninjectKernel; #endregion #region Properties #endregion #region Methods protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, System.Type controllerType) { return controllerType == null ? null : (IController) ninjectKernel.Get(controllerType); } private void AddBindings() { ninjectKernel.Bind<IProductRepository>().To<EFProductRepository>(); EmailSettings emailSettings = new EmailSettings { WriteAsFile = bool.Parse(ConfigurationManager.AppSettings["Email.WriteAsFile"] ?? "false") }; ninjectKernel.Bind<IOrderProcessor>().To<EmailOrderProcessor>().WithConstructorArgument("settings", emailSettings); ninjectKernel.Bind<IAuthProvider>().To<FormsAuthProvider>(); } #endregion } }Which is then invoked in the Global.asax like so:
Later in the book it suggests that this approach can lead to duplication of code and also the risk of numerous Ninject Kernels and instructs the following instead using the DependencyResolver:
using System; using System.Collections.Generic; using System.Configuration; using System.Web.Mvc; using Ninject; using Ninject.Syntax; using SportsStore.Domain.Abstract; using SportsStore.Domain.Concrete; using SportsStore.WebUI.Infrastructure.Abstract; using SportsStore.WebUI.Infrastructure.Concrete; namespace SportsStore.WebUI.Infrastructure { public class NinjectDependencyResolver : IDependencyResolver { private IKernel kernel; public NinjectDependencyResolver() { kernel = new StandardKernel(); AddBindings(); } public object GetService(Type serviceType) { return kernel.TryGet(serviceType); } public IEnumerable<object> GetServices(Type serviceType) { return kernel.GetAll(serviceType); } public IBindingToSyntax<T> Bind<T>() { return kernel.Bind<T>(); } public IKernel Kernel { get { return kernel; } } private void AddBindings() { //Put additional bindings here Bind<IProductRepository>().To<EFProductRepository>(); Bind<IAuthProvider>().To<FormsAuthProvider>(); //Create the email settings object EmailSettings emailSettings = new EmailSettings { WriteAsFile = bool.Parse(ConfigurationManager.AppSettings["Email.WriteAsFile"] ?? "false") }; Bind<IOrderProcessor>().To<EmailOrderProcessor>().WithConstructorArgument("settings", emailSettings); } } }Globals.asax uses this like so:
I just wondered if someone can explain why the 2nd approach is better as the code seems similar?
Thank, Dave.
CPrakash82
All-Star
18284 Points
2841 Posts
Re: DependencyResolver why is this preferable to DefaultControllerFactory
Jun 25, 2012 10:32 PM|LINK
You can find several blog on this topic and it is not possible to sum it up in few lines. But I will try to make it simple.
The way MVC2's DefaultControllerFactory works is, it first create controller type from the controller name and then creates the instance of it by using Activator.CreateInstance.
But in MVC3 it has been greatly simplfies by providing two interfaces IControllerActivator & IDependencyResolver, now DefaultControllerFactory will call dependency resolver to resolve instance of IControllerActivator by calling GetService Method. If dependency resolver fails to resolve the Controller Instance it will again go back to MVC2's way to create the controller instance.
Please go through the articles below it will give you in depth knowledge about it.
http://bradwilson.typepad.com/blog/2010/10/service-location-pt10-controller-activator.html
http://weblogs.asp.net/shijuvarghese/archive/2011/01/21/dependency-injection-in-asp-net-mvc-3-using-dependencyresolver-and-controlleractivator.aspx
Thanks,
bigredhf
Member
48 Points
81 Posts
Re: DependencyResolver why is this preferable to DefaultControllerFactory
Jun 25, 2012 10:54 PM|LINK
Thanks for your reply.
I have looked at the links you provided and in fact your explanation is to the point. I think at this stage I am asking a lot of questions some of which will be apparent as I move on. Anyway I feel happy to go this way with DI now!
Thanks very much again!!!! :)
CPrakash82
All-Star
18284 Points
2841 Posts
Re: DependencyResolver why is this preferable to DefaultControllerFactory
Jun 25, 2012 10:56 PM|LINK
Great, hope you will enjoy working with MVC, questioning is always good.
Thanks,