【转】Understanding Inversion of Control, Dependency Injection and Service Locator Print
-----------------------------------------------------------------------------------------
Understanding Inversion of Control, Dependency Injection and Service Locator
So many developers are confused about the the term Dependency Injection (DI). The confusion is about terminology, purpose, and mechanics. Should it be called Dependency Injection, Inversion of Control, or Service Locator? Over the Internet, there are a lot of articles, presentations and discussion but, unfortunately, many of them use conflicting terminology. In this article I would like to explain, all these three OOPS concepts.
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.
The Dependency Inversion principle (DIP) helps us to develop loosely couple code by ensuring that high-level modules depend on abstractions rather than concrete implementations of lower-level modules. The Inversion of Control pattern is an implementation of this principle
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.

More over IoC is a generic term and it is not limited to DI. Actually, DI and Service Locator patterns are specialized versions of the IoC pattern or you can say DI and Service Locator are the ways of implementing IoC.
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.

Now have a look at the folllowing code:
- 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
- }
- }
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.
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

The above code can be re-written as by using Service Locator as follows.
- 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
- }
- }
Sample ServiceLocator-Implementation:
- class Program
- {
- static void Main(string[] args)
- {
- var client = new Client();
- client.Start();
- Console.ReadKey();
- }
- }
The Inversion happens in the constructor, by locating the Service that implements the IService-Interface. The dependencies are assembled by a "Locator".
Using Dependency Injection

The above code can also be re-written as by using Dependency Injection as follows.
- 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
- }
- }
Sample Builder-Implementation:
- class Program
- {
- static void Main(string[] args)
- {
- client = new Client(new Service());
- client.Start();
- Console.ReadKey();
- }
- }
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:
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.
References
http://www.objectmentor.com/resources/articles/dip.pdf
http://satoricode.net/2011/10/01/UnderstandingTheBenefitsOfADependencyInjectionContainerIOC.aspx
What do you think?
I hope you will enjoy the DIP, IoC, DI and SL patterns. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.
【转】Understanding Inversion of Control, Dependency Injection and Service Locator Print的更多相关文章
- Inversion of Control Containers and the Dependency Injection pattern(转)
In the Java community there's been a rush of lightweight containers that help to assemble components ...
- Inversion of Control Containers and the Dependency Injection pattern--Martin Fowler
原文地址:https://martinfowler.com/articles/injection.html n the Java community there's been a rush of li ...
- [转载][翻译] IoC 容器和 Dependency Injection 模式
原文地址:Inversion of Control Containers and the Dependency Injection pattern 中文翻译版本是网上的PDF文档,发布在这里仅为方便查 ...
- Dependency Injection
Inversion of Control - Dependency Injection - Dependency Lookup loose coupling/maintainability/ late ...
- 控制反转Inversion of Control (IoC) 与 依赖注入Dependency Injection (DI)
控制反转和依赖注入 控制反转和依赖注入是两个密不可分的方法用来分离你应用程序中的依赖性.控制反转Inversion of Control (IoC) 意味着一个对象不会新创建一个对象并依赖着它来完成工 ...
- Inversion of Control Containers and the Dependency Injection pattern
https://martinfowler.com/articles/injection.html One of the entertaining things about the enterprise ...
- 控制反转(Inversion of Control,英文缩写为IoC),另外一个名字叫做依赖注入(Dependency Injection,简称DI)
控制反转(Inversion of Control,英文缩写为IoC),另外一个名字叫做依赖注入(Dependency Injection,简称DI),是一个重要的面向对象编程的法则来削减计算机程序的 ...
- AngularJs学习笔记--Dependency Injection(DI,依赖注入)
原版地址:http://code.angularjs.org/1.0.2/docs/guide/di 一.Dependency Injection(依赖注入) 依赖注入(DI)是一个软件设计模式,处理 ...
- 控制反转(Inversion of Control)之我的理解
关于控制反转(Inversion of Control),在具体实现上也有许多其它的叫法,如依赖倒置(Dependency Inversion Principles, DIP).依赖注入(Depend ...
随机推荐
- 3.6 Lucene基本检索+关键词高亮+分页
3.2节我们已经运行了一个Lucene实现检索的小程序,这一节我们将以这个小程序为例,讲一下Lucene检索的基本步骤,同时介绍关键词高亮显示和分页返回结果这两个有用的技巧. 一.Lucene检索的基 ...
- 学习C++ -> 向量(vector)
一.向量的介绍 向量 vector 是一种对象实体, 能够容纳许多其他类型相同的元素, 因此又被称为容器. 与string相同, vector 同属于STL(Standard Template Lib ...
- 百度之星初赛(A)——T1
小C的倍数问题 Problem Description 根据小学数学的知识,我们知道一个正整数x是3的倍数的条件是x每一位加起来的和是3的倍数.反之,如果一个数每一位加起来是3的倍数,则这个数肯定是3 ...
- 汕头市队赛 SRM10 T3 数学上来先打表
数学上来先打表 SRM 10 描述 给出 n个点(不同点之间有区别),求出满足下列条件的连边(双向边)方案:1.每条边连接两个不同的点,每两个点之间至多有一条边2.不存在三个点a,b,c使三个点间两两 ...
- php 内核变量 引用计数器写时复制
写时复制,是一个解决内存复用的方法,就是你在php语言层,如$d=$c=$b=$a='value';把$a赋给另一个或多个变量,这时这个变量都只占用一个内存块,当其中一个变量值改变时,才会开辟另一个内 ...
- Kali安装到移动硬盘或者U盘中~Linux系通用方法(包括Android)
0.1.保证这个服务必须启动(虚拟机服务最好都启动) 0.2.看看U盘接口类型是否对应 1.安装第一步 2.安装第二步,选择kali镜像 3.设置存放位置(上面的名字无所谓,最后不会用它的,虚拟机只是 ...
- 2018多校第三场 hdu6331 M :Walking Plan
题目链接 hdu6331 自我吐槽,这场多校大失败,开局签到因输入输出格式写错,wa了3发.队友C题wa了1个小时,还硬说自己写的没错,结果我随便造了个小数据,他都没跑对.然后跑对了后又进入了无限的卡 ...
- 杭电oj2064、2067、2068、2073、2076-2078、2080、2083-2085
2064 汉诺塔III #include<stdio.h> int main(){ int n,i; _int64 s[]; while(~scanf("%d",&a ...
- 有关cookie的内容
包括: Cookie概述(Cookie的存放,有效期和作用域) Cookie操作(保存Cookie,读取Cookie,Cookie的生命周期) Cookie工作原理(Cookie与会话跟踪,Cooki ...
- ubuntu安装ftp server并匿名访问
$ sudo apt install vsftpd //修改添加以下配置 $ sudo vim /etc/vsftpd.conf #listen_ipv6=YES #注销ipv6监听 listen=Y ...