Today I would like to share my thoughts on dependency injection in MVC. If you are not familiar with MVC, i would suggest to read my article about MVC first.
What is Dependency Injection?
In simple words dependency injection (DI) means injecting a new functionality (let say X) to a base functionality without making any changes it. Later, functionality X can be replaced by Functionality Y with no impact on base functionality.Why Dependency Injection?
There could be large number components in your application, which are likely to get changed or to be extended in future. In order make your design flexible to accommodate these kind of changes, you would need to build your components as loosely coupled, so that they can be plugged or unplugged as and when required. Moreover, each components can be built and tested independently without impacting other components.How to achieve Dependency Injection in MVC?
Although DI can be achieved in many ways. The approach that I would take here is, programming the components against a interface.
In order to make it more clear, let say you need to build a functionality to export a file in to MS Word format. The approach here would be define standard interface; IExportHandler and implement your document export functionality against that interface.
CODE-XP |
Now download functionality can export a file in to MSWord format by calling Export method of IExportHandler
CODE-XP |
Let say in future, if there is requirement to download file in PDF or XPS format instead of MS Word then we just need to create implementation of PdfExportHandler.
Class PdfExportHandler :IExportHandler
{
public byte[] Export(byte[] filebyte)
{
//PDF export logic goes here
}
}
There is no need to change the piece of code that handles download functionality. This because we have programmed to an interface. All types of export functionality is consumed via interface.
Class PdfExportHandler :IExportHandler
{
public byte[] Export(byte[] filebyte)
{
//PDF export logic goes here
}
}
There is no need to change the piece of code that handles download functionality. This because we have programmed to an interface. All types of export functionality is consumed via interface.
Now one question that comes to your mind is who will pass the appropriate concrete implementation of IExportHandler to DownloadFile method. The answer is DI container. These are standalone libraries that manages creation and destruction of application objects. The DI container that I will be using here is : Microsoft unity framework.
Integrating Unity framework in mvc
This can be done by running following command from Package Manager console in Visual studio
Install-Package Unity
Creating custom controller factory
The IControllerFactory is interface that deals with creation and destruction of controller objects in MVC. This interface should be implemented by a new class: UnityControllerFactory to override the default behavior of object creation.
CODE-XP
|
Register custom controller factory
Create bootstrapper class that registers WordExportHandler class under DI container, so that word export functionality can be injected, wherever the interface IExportHandler is referred in the main applicationSecondly register custom controller factory under ControllerBuilder class
CODE-XP |
Now we need to invoke the IntializeDI method of bootstrapper class inside app_start event of MVC application. This will take care of initialization of DI and controller factory.
Finally in the controller class, we need to create constructor that can accept instance of IExportHandler Interface.
When user request for file download, unity framework takes care of creating instance of WordExportHandler and passing it to the FileDownloadController constructor.
CODE-XP |
Conclusion
This is a simple example, how you can achieve loose coupling in your application and handle any future requirement changes. This can be extended through out the application to yield more benefits.This is all I have for now. For more interesting articles, keep watching my blog.
Happy coding
MK.
No comments:
Post a Comment