Overview
This article explains Dependency Injection (DI) in MVC 3 applications.
Introduction
This article explains the code from Basics of MVC3 Part - 1
and Part - 2,
so please have a look at these articles before starting MVC 3 Dependency Injection (Part – 3).
The Dependency Injection (DI) Design Pattern
The Dependency Injection (DI) design pattern is based on separating component behavior from dependency resolution without object intervention.
This pattern is a particular implementation of Inversion of Control, where the consumer object receives its dependencies inside constructor properties or arguments.
The advantages of using the Dependency Injection pattern and Inversion of Control are the following:
- Reduces class coupling
- Increases code reuse
- Improves code maintainability
- Improves application testing
Implementing DI in the MVC3Demo project
Create a UnityControllerFactory Class
Create a UnityControllerFactory
(custom class) for Unity. This class implements the IControllerFactory
interface, extending the CreateController
and ReleaseController
methods to work with Unity.
The CreateController
method creates an instance of the controllers available in the project.
Please download Unity Application Block 2.0 and install it. Then refer to Microsoft.Practices.Unity
in the MVC3Demo project.
Step 1
Add a new folder named Factories and add a class UnityControllerFactory.cs.
namespace MVC3Demo.Factories
{
public class UnityControllerFactory : IControllerFactory
{
private IUnityContainer _container;
private IControllerFactory _factory;
public UnityControllerFactory(IUnityContainer container)
: this(container, new DefaultControllerFactory()) { }
public UnityControllerFactory(IUnityContainer container, IControllerFactory factory)
{
_container = container;
_factory = factory;
}
public IController CreateController(System.Web.Routing.RequestContext requestContext,
string controllerName)
{
try
{
return _container.Resolve<IController>(controllerName);
}
catch (Exception)
{
return _factory.CreateController(requestContext, controllerName);
}
}
public System.Web.SessionState.SessionStateBehavior
GetControllerSessionBehavior(
System.Web.Routing.RequestContext requestContext, string controllerName)
{
return System.Web.SessionState.SessionStateBehavior.Default;
}
public void ReleaseController(IController controller)
{
_container.Teardown(controller);
}
}
}
Create Interface for ProductModel
Step 2
Right click the ProductModel
class and click the Refactor->Extract Interface menu.
and click OK.
Refactory ProductController Class
Refer to the IProductModel
interface instead of the ProductModel
concrete class in the constructor of the ProductController
class.
IProductModel model = null;
IList<ProductModel> AllProducts = null;
public ProductController(IProductModel _model)
{
model = _model;
AllProducts = model.GetAllProducts();
}
No Parameterless Constructor Error
Build and run the MVC3Demo application, it gives No Prameterless constructor defined for this object. The ProductController
constructor
has an argument IProductModel
.
Configuring UnityContainer
Step 3
Configure the Interface and its concrete class using RegisterType
and create an instance of the custom controller factory UnityControllerFactory
and pass this into ControllerBuilder
.
Please see the code below.
private void RegisterType()
{
UnityContainer container = new UnityContainer();
container.RegisterType<IProductModel, ProductModel>();
container.RegisterType<IController, ProductController>("Product");
UnityControllerFactory factory = new UnityControllerFactory(container);
ControllerBuilder.Current.SetControllerFactory(factory);
}
Create this method in Global.asax.cs and call the RegisterType
method at the end of the Application_Start()
event.
Please refer to the attached code zip for detailed application code.
Conclusion
I hope this article helps to understand some of the basics of Dependency Injection (DI) in MVC 3 applications.
References
- http://msdn.microsoft.com/en-us/gg618491
-
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=9093
- http://msdn.microsoft.com/en-us/library/ff663144.aspx