The Dependency Injection Pattern is a popular design technique that can be used to implement loosely coupled, reusable, and testable objects in your software designs by reducing the cohesion amongst the components in your application. You can implement dependency injection in your applications to promote loose coupling, centralized configuration and make your application easier to test and maintain. The Wikipedia states: “Dependency injection (DI) in object-oriented computer programming is a technique for supplying an external dependency (i.e. a reference) to a software component – that is, indicating to a part of a program which other parts it can use. It is a specific form of inversion of control where the concern being inverted is the process of obtaining the needed dependency.”
Reference: http://en.wikipedia.org/wiki/Dependency_injection
By creating an instance of a class within another, you are immediately creating a dependency and tightly coupling your code. Dependency Injection is a technique for decoupling highly dependent software components.
Dependency Injection Principle (DIP) is all about isolating your classes from the concrete implementations and having them depend on abstract classes or interfaces.
You can find below class full of dependencies.
public class ReturnOrderService { private EmailNotificationService _notificationService; //Dependency private ProductService _productService;//Dependency public ReturnOrderService() { _notificationService = new EmailNotificationService(); _productService = new ProductService (); } }
ReturnOrderService is dependent on the lower – level modules of the EmailNotificationService and ProductService. However, service should only deal with the real business logic and workflow and not be responsible for the construction of lower – level details.
Now create the interfaces for lower-lower details
public interface IProductService { void ReturnStockFor(ReturnOrder ReturnOrder); } public class ProductService : IProductService { ... } public class ReturnOrderService { private IEmailNotificationService _notificationService; private IProductService _productService; public ReturnOrderService (INotificationService notificationService, IProductService productService) { _notificationService = notificationService; _productService = productService; } }
After applying constructor injection to the ReturnOrderService class, it no longer needs to know which payment gateway implementation to instantiate and it no longer needs to know how to instantiate it.
Types of Dependency Injection
Dependency Injection can be one of the following types:
- Constructor Injection
- Setter Injection
- Interface-based injection
- Service Locator
Constructor Injection: Injecting dependencies through the class constructor.
public class ReturnOrderService { private INotificationService _notificationService; ... public ReturnOrderService(INotificationService notificationService) { _notificationService = notificationService; ... } }
Setter Injection: Injecting dependent modules via a setter property on the dependent module.
public class ReturnOrderService { public INotificationService NotificationService { get ; set ; } ... Public ReturnOrderService() { ... } }
Interface based Dependency Injection: Requires the dependency to implement an interface that the high-level module will reference and inject at runtime.
It is much more appropriate to use this approach when you need to have some logic that is not applicable to place in a property. Such as logging support.
public void SetLogger(ILogger logger) { _notificationService.SetLogger(logger); _productService.SetLogger(logger); }
Service Locator
The other way to inject dependency is by using service locator. Your main class which will aggregate the child object will use the service locator to obtain instance of the address object. The service locator class does not create instances of the address object, it provides a methodology to register and find the services which will help in creating objects.
static class LocateAddress { public static IAddress getAddress() { ....... } } public class clscustomer { private IAddress _address; public clscustomer() { _address = LocateAddress.getAddress(); } .......... .......... }
Adantages Of DI
- Reduced Dependencies
- More Reusable Code
- More Testable Code
- More Readable Code
- Reduced Dependency Carrying
Reference:
http://www.codeproject.com/KB/aspnet/IOCDI.aspx
Similar Topics:
- Implementing Abstract Factory Pattern in .net
- Repository Pattern in .net
- Implementing Factory Pattern in .net
- Introduction To Model-View-ViewModel (MVVM) Pattern
- Test Driven Development guide
- Implementing Unit of Work Pattern in .net
- Outlook Web Access corrupts HTML attachments