Dependency Inversion Principle (DIP)
The Dependency Inversion Principle states that: - High level modules should not depend upon low level modules. Both should depend upon abstractions.
- Abstractions should not depend upon details. Details should depend upon abstractions.
Inversion of Control (IoC)
The term Inversion of Control (IoC) refers to a programming style where a framework or runtime, controls the program flow. Inversion of control means we are changing the control from normal way. It works on Dependency Inversion Principle. The most software developed on the .NET Framework uses IoC.For example
- When you write an ASP.NET application, you lie into the ASP.NET page life cycle, but you aren’t in control while ASP.NET is.
- When you write a WCF service, you implement interfaces decorated with attributes. You may be writing the service code, but ultimately, you aren’t in control while WCF is.

For example, Suppose your
Client
class needs to use a Service
class component, then the best you can do is to make your Client
class aware of an IService
interface rather than a Service
class. In this way, you can change the implementation of the Service
class at any time (and for how many times you want) without breaking the host code.IoC and DIP
DIP says High level module should not depend on low level module and both should depend on abstraction. IoC is a way that provide abstraction. A way to change the control. IoC gives some ways to implement DIP. If you want to make independent higher level module from the lower level module then you have to invert the control so that low level module not controlling interface and creation of the object. Finally IoC gives some way to invert the control.
IoC and DI
The terms Dependency Injection (DI) & Inversion of Control (IoC) are generally used interchangeably to describe the same design pattern. The pattern was originally called IoC, but Martin Fowler proposed the shift to DI because all frameworks invert control in some way and he wanted to be more specific about which aspect of control was being inverted.Dependency Injection (DI)
DI is a software design pattern that allow us to develop loosely coupled code. DI is a great way to reduce tight coupling between software components. DI also enables us to better manage future changes and other complexity in our software. The purpose of DI is to make code maintainable.The Dependency Injection pattern uses a builder object to initialize objects and provide the required dependencies to the object means it allows you to "inject" a dependency from outside the class.
Service Locator (SL)
Service Locator is a software design pattern that also allow us to develop loosely coupled code. It implements the DIP principle and easier to use with an existing codebase as it makes the overall design looser without forcing changes to the public interface.The Service Locator pattern introduces a locator object that objects is used to resolve dependencies means it allows you to "resolve" a dependency within a class.
Dependency Injection and Service Locator with Example
Let's consider the simple dependency between two classes as shown in the fig and it is a simple approach, that you know.
Clearly, the Client class has a dependency on the Service class. If you want to make it loosely coupled, you have to use IoC to make the more flexible and reusable it.
- public class Service
- {
- public void Serve()
- {
- Console.WriteLine("Service Called");
- //To Do: Some Stuff
- }
- }
- public class Client
- {
- private Service _service;
- public Client()
- {
- this._service = new Service();
- }
- public void Start()
- {
- Console.WriteLine("Service Started");
- this._service.Serve();
- //To Do: Some Stuff
- }
- }
To implement the IoC, you have the choice of two main patterns: Service Locator and Dependency Injection. The Service Locator allows you to "resolve" a dependency within a class and the Dependency Injection allows you to "inject" a dependency from outside the class.
Using Service Locator

Sample ServiceLocator-Implementation:
- public interface IService
- {
- void Serve();
- }
- public class Service : IService
- {
- public void Serve()
- {
- Console.WriteLine("Service Called");
- //To Do: Some Stuff
- }
- }
- public static class LocateService
- {
- public static IService _Service { get; set; }
- public static IService GetService()
- {
- if (_Service == null)
- _Service = new Service();
- return _Service;
- }
- }
- public class Client
- {
- private IService _service;
- public Client()
- {
- this._service = LocateService.GetService();
- }
- public void Start()
- {
- Console.WriteLine("Service Started");
- this._service.Serve();
- //To Do: Some Stuff
- }
- }
The Inversion happens in the constructor, by locating the Service that implements the IService-Interface. The dependencies are assembled by a "Locator".
- class Program
- {
- static void Main(string[] args)
- {
- var client = new Client();
- client.Start();
- Console.ReadKey();
- }
- }
Using Dependency Injection

Sample Builder-Implementation:
- public interface IService
- {
- void Serve();
- }
- public class Service : IService
- {
- public void Serve()
- {
- Console.WriteLine("Service Called");
- //To Do: Some Stuff
- }
- }
- public class Client
- {
- private IService _service;
- public Client(IService service)
- {
- this._service = service;
- }
- public void Start()
- {
- Console.WriteLine("Service Started");
- this._service.Serve();
- //To Do: Some Stuff
- }
- }
The Injection happens in the constructor, by passing the Service that implements the IService-Interface. The dependencies are assembled by a "Builder" and Builder responsibilities are as follows:
- class Program
- {
- static void Main(string[] args)
- {
- client = new Client(new Service());
- client.Start();
- Console.ReadKey();
- }
- }
- knowing the types of each IService
- according to the request, feed the abstract IService to the Client
What's wrong with the above two approaches?
Above two approaches can be resemble to DI FACTORY. There are some issues with the above two approaches:- It is hardcoded and can't be reused across applications, due to
hardcoded factories. This makes the code stringent to particular
implementations.
- It is Interface dependent since interfaces are used for decoupling the implementation and the object creation procedure.
- It's Instantiating instantiations are very much custom to a particular implementation.
- Everything is compile time since all the dependent types for the objects in the instantiation process (factory) have to be known at compile time.
What is the Solution ?
IoC containers is the solution to resolve above two approaches
issues. Hence, when we compose applications without a DI CONTAINER, it
is like a POOR MAN’S DI
. Moreover, DI CONTAINER is a useful, but optional tool.You can also improve above two approaches by doing some more work. You can also combine above two approaches to make code more independent
Dependency Injection VS Service Locator
- When you use a service locator, every class will have a dependency on your service locator. This is not the case with dependency injection. The dependency injector will typically be called only once at startup, to inject dependencies into the main class.
- The Service Locator pattern is easier to use in an existing
codebase as it makes the overall design looser without forcing changes
to the public interface. Code that is based on the Service Locator
pattern is less readable than the equivalent code that is based on
Dependency Injection.
The advantages of using Dependency Injection pattern and Inversion of Control are the following:
- Reduces class coupling
- Increases code reusing
- Improves code maintainability
- Improves application testing
Factory Pattern and the separation between the interface and the implementation using services, where the client objects are often responsible for service location.
The Dependency Injection pattern is a particular implementation of Inversion of Control. Inversion of Control (IoC) 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).
Dependency Injection (DI) means that this is done without the object intervention, usually by a framework component that passes constructor parameters and set properties.
No comments:
Post a Comment