May 24, 2012

Custom Controller Factory

Constructor Injection is the DI technique of passing an object's dependencies to its constructor. But this by default will not work with Mvc unless you have a parameterless constructor also defined. If you try to run, it will throw error stating that “No parameterless constructor is defined for this object”. A way to get around this and have DI is by defining both parameterless constructor as well as one with which you want to have dependency.

public class ProductController : Controller
    {
        #region Constructor
        
        public ProductController()
            : this(new ProductModel())
        {
        }

        public ProductController(IProductModel productModel)
        {
            if (productModel == null)
                throw new ArgumentNullException("productModel");
            ProductModel = productModel;
        }

        private IProductModel ProductModel { get; set; } 

        #endregion

The other way to achieve this is by defining CustomeControllerFactoryWithoutDefaultConstructor something like this

public class CustomeControllerFactoryWithoutDefaultConstructor : DefaultControllerFactory
    {
        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            return Activator.CreateInstance(controllerType, new ProductModel()) as IController;
        }
    }

And then register this in Global.asax:

ControllerBuilder.Current.SetControllerFactory(typeof(CustomeControllerFactoryWithoutDefaultConstructor));

Dependency Injection DI/IoC

Dependency Injection (DI) means that this is done without the object intervention. In other words the object dependency is on interfaces and not on concrete objects. This promotes greater reusability, easier maintainability, and mockability unit test. Thsi is also referred as Inversion of Control (IoC) which means that objects do not create other objects on which they rely to do their work. Instead, they get the objects that they need from an outside source (for example, an xml configuration file).

Constructor Injection
Constructor Injection is the DI technique of passing an object's dependencies to its constructor.

 public class ProductController 
 {
  public ProductController(IProductModel productModel)
  {
   if (productModel == null)
    throw new ArgumentNullException("productModel");
   ProductModel = productModel;
  }

From the above it is clear to the developer invoking the object, which dependencies need to be given to the ProductController object for proper execution.

Consider a case where you have lots of methods with no dependencies and you are adding a new method that does have a dependency on IProductModel. So one way is to change the constructor to use Constructor Injection, but this will require changes to all existing constructor calls. So alternatively, you could just add a new constructor that takes the dependency.

 public class ProductController 
 {
  public ProductController()
  {
  
  }
  public ProductController(IProductModel productModel)
  {
   if (productModel == null)
    throw new ArgumentNullException("productModel");
   ProductModel = productModel;
  }

Now some one can argure how does a developer easily know when to use one constructor over the other.

The other case is, if the dependency is very expensive to create, why should it be created and passed to the constructor when it may only be used rarely? "Setter Injection" is another DI technique that can be used in situations such as this.

Setter Injection
In this case dependencies are set onto public properties exposed by the object in need.

 public class ProductController 
 {
  public ProductController()
  {
  
  }
  
  public IProductModel ProductModel { get; set; } 

Few things to consider here
 . In this case it does not make very clear when dependency need to be create as in case of constructor Injection.
. Also note that in constructor Injection we an exception is thrown if the dependency is not set immediately, where as with Setter Injection, an exception isn't thrown until a method actually attempts to use the dependency.

Injectors
Now someone has to create the dependency. One of the approach is to use "DI controller". In the following Mvc example I have two constructors default and the other with parameter. The framework will use default constructor where as for unit testing one can use the one which has parameter so that it can be easily mockable.

 public class ProductController : Controller
    {
        #region Constructor
        //
        // GET: /Product/
        public ProductController()
            : this(new ProductModel())
        {
            TempDataProvider = new CustomeTempDataProvider();
        }

        public ProductController(IProductModel productModel)
        {
            if (productModel == null)
                throw new ArgumentNullException("productModel");
            ProductModel = productModel;
        }

        public IProductModel ProductModel { get; set; } 

Even if "controller" is not well defined if you see at a high level in any properly tiered architecture "controller" layer always exists. For example in ASP.NET, the code-behind page acts as a controller layer.

The other approach is to use DI Containers. There are some frameworks (Spring .NET, Windsore) which allows you to define dependency injections within an XML file.