Consider a typical scenario where we have a client class which calls another class (can be referred here as service class as it provides service to the calling client class). So the client class has dependency with a specific service class. Now later if there is a new service to be invoked by the client then we need to rewrite the client class in the area where the existing service class to be replaced with new service class. This is called dependency of the client with its service class and its clear example of tight coupling. Dependency injection is a design pattern which eliminates this type of dependency of a class independent of its dependencies.
This DI is an example of one way of achieving the
Dependency Inversion principle found in the SOLID philosophy. The practice of
dependency injection is made possible by following the dependency inversion
principle.
Typical code without DI pattern will look like as given
below:
using System; namespace DISample { class Program { static void Main(string[] args) { Customer objClient=new Customer(); string orderResponse = objClient.OrderFood(); Console.WriteLine(orderResponse); } } Public class Customer { public string OrderFood() { Zomato objShopAService=new Zomato(); return objShopAService.Order(); } } Public class Zomato { public string Order() { return "Thanks for ordering in Zomato. Please wait we are going to deliver asap."; } } public class Swiggy { public string Order() { return "Thanks for ordering in Swiggy. Your food will be delivered soon by our courier guy."; } } Public class UberEats { public string Order() { return "Thanks for ordering in UberEats. We are sending your food now!"; } } }
So what if the client class here (i.e. Customer changes his mind to place the order from UberEats instead of Zomato. Since the customer class is currently tightly coupled as per the implementation we need code to be recompiled whenever the client wishes to change its services. And this implementation is difficult to unit test.
Now let us use the how DI design pattern helps to decouple the classes and how the class can be independent from the creation of the objects it depends on.
There are 4 components in the DI design pattern which helps in achieving this pattern:
1. Client class; client class depends on the service class(in sample its Customer class)
2. Service class; which provides service to the client
class(in sample its Swiggy,Zomato,UberEats class)
3. Interface: (the interface which defines the contract
of the service class, interface is IOnlineFoodDelivery in below sample. As the Dependency Inversion Principle suggests modules should depend on abstractions. So to have the abstractions implemented we go for an abstraction with the help of interface)
4. Injector: (Injector class injects the service class object
into the client class, injector is done in Main() of Program class in below
sample)
using System; namespace DISample { class Program { static void Main(string[] args) { Customer objCust=new Customer(new Zomato()); } } public class Customer { IOnlineFoodDelivery _iOnlineFoodDelService; public Customer(IOnlineFoodDelivery pIOnlineFoodDelivery) { _iOnlineFoodDelService=pIOnlineFoodDelivery; Console.WriteLine(_iOnlineFoodDelService.Order()); } } public interface IOnlineFoodDelivery { public string Order(); } public class Zomato:IOnlineFoodDelivery { public string Order() { return "Thanks for ordering in Zomato. Please wait we are going to deliver asap."; } } public class Swiggy:IOnlineFoodDelivery { public string Order() { return "Thanks for ordering in Swiggy. Your food will be delivered soon by our courier guy."; } } public class UberEats:IOnlineFoodDelivery { public string Order() { return "Thanks for ordering in UberEats. We are sending your food now!"; } } }
Types of Dependency Injection:
Dependency injection is an example of design pattern which implements the Inversion of Control(IoC). IoC is a programming principle, IoC inverts the flow of control as compared to traditional control flow.
Inversion of control serves the following design purposes:
To focus a module on the task it is designed for.
To free modules from assumptions about how other systems do what they do and instead rely on contracts.
To prevent side effects when replacing a module.
Inversion of control is sometimes facetiously referred to as the "Hollywood Principle: Don't call us, we'll call you".
0 comments:
Post a Comment