依赖是什么
一般情况下,如果服务 A 需要服务 B,那就意味着服务 A 要在内部创建服务 B 的实例,也就说服务 A 依赖于服务 B
依赖注入是什么
依赖注入(Dependency Injection,简称DI)是一种软件设计模式,在这种模式下, 一个或更多的依赖(或服务)被注入(或者通过引用传递)到一个独立的对象(或客户端)中,然后成为了该客户端状态的一部分。 该模式分离了客户端依赖本身行为的创建,这使得程序设计变得松耦合,并遵循了依赖反转和单一职责原则。与服务定位器模式形 成直接对比的是,它允许客户端了解客户端如何使用该系统找到依赖 .
控制反转 (inversion of control,IoC) 原则的非正式称谓是“好莱坞法则”。它来自好莱坞的一句常用语“别打给我们,我们会打给你 (don’t call us, we’ll call you)”。
当你的app的某处声明需要用到某个依赖时,Angular 会调用这个依赖注入器去查找或是创建你所需要的依赖,然后返回来给你用
这样做的好处是
- 松耦合和可重用性
- 提高可测试性,服务B被抽出来后,就不用去管他了,只用测试服务A
获得对依赖的控制权
对象或函数可以通过三种方式获得所以依赖的对象
- 在内部创建依赖:这种方法的弊端就是不方便以后的维护,使隔离变的异常困难。
- 通过全局变量进行引用:这种方法的弊端就是污染了全局作用域,当代码量达到了一定程度后,容易出现问题。
- 在需要的地方进行参数传递:这种方法不仅对测试很有用,而且不会污染全局变量,是很好的设计模式。AngularJS用的就是这种方法。
Angular依赖注入的方法
AngularJS通过注入器调用某些功能(例如服务工厂和控制器)。您需要注释(Annotation)
这些功能,以便注入器知道要向该函数注入哪些服务。可以使用三种方法用服务名称信息来注释代码:
- 使用内联数组注释(首选)
- 使用
$inject
属性注释 - 从函数参数名称隐式(有警告)
使用内联数组注释
someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
// ...
}]);
在这里,我们传递一个数组,该数组的元素由字符串列表(依赖项的名称)和函数本身组成。
使用这种类型的注释时,请注意使注释数组与函数声明中的参数保持同步。
$Inject
属性注释
var MyController = function($scope, greeter) {
// ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);
在这种情况下,$inject数组中值的顺序必须与中的参数顺序匹配MyController。
隐式注释
someModule.controller('MyController', function($scope, greeter) {
// ...
});
这种方式,看上去比前两种精简了不少,不用多写一遍依赖项,也不用考虑和参数顺序同步的问题,但是这么写有个弊端,在发布的时候,往往要压缩JavaScript代码,压缩时,会替换掉变量名。比如
s
c
o
p
e
会
替
换
成
长
度
更
小
的
a
,
但
是
scope会替换成长度更小的a,但是
scope会替换成长度更小的a,但是scope这个名字又是不能改动的,否则会无法识别。所以这种隐式的依赖注入方法不好。
Note: AngularJS uses constructor injection.AngularJS 使用构造函数注入
参考
https://blog.csdn.net/zach90/article/details/82560204
http://semlinker.com/ng-di/
https://blog.csdn.net/jaytalent/article/details/50986402
http://www.pianshen.com/article/4658300953/
https://segmentfault.com/a/1190000002786133
https://www.jb51.net/article/117189.htm
https://docs.angularjs.org/guide/di