使用$ injector与直接注入服务 [英] Using $injector vs injecting a service directly
问题描述
我想知道您何时使用$injector.get('someService')
而不是直接注入该服务.
I was wondering when would you use $injector.get('someService')
vs injecting that service directly.
基本上,下面的两个代码有什么区别?
Basically, what is the difference of the two code below?
angular
.module('myApp')
.controller('MyController', MyController);
/** Difference of this **/
MyController.$inject = ['$rootScope', '$route']; // and more services
MyController($rootScope, $route)
{
/* ... */
}
/** And this **/
MyController.$inject = ['$injector'];
MyController($injector)
{
var $rootScope = $injector.get('$rootScope');
var $route = $injector.get('$route');
/* and so on */
}
如果不确定控制器需要什么,或者将来会更新它,并对其进行重构,则使用$injector
可以轻松添加/删除依赖项.
If you are not sure what your controller needs, or that you will update it in the future, and you have it refactored, then using $injector
it is a lot easier to add/remove dependencies.
推荐答案
第一种方法使用依赖项注入,第二种方法使用服务定位器模式.依赖注入具有以下优点:
The first approach uses dependency injection while the second uses service locator pattern. Dependency injection has the following advantages:
-
它使组件的依赖关系显式化.例如,您可以查看控制器的构造函数,并立即知道它需要什么依赖关系.使用服务定位器,您通常不知道,因为控制器可以随时调用服务定位器.
It makes a component's dependencies explicit. For example, you can look at the constructor function of a controller and immediately know what dependencies it needs. With service locator, you usually have no idea because the controller might invoke the service locator any time.
这使单元测试更加容易.例如,您可以使用$controller
服务实例化控制器,并通过locals
参数将其提供给模拟对象.这肯定比必须定义一堆AngularJS服务或工厂要容易得多,以便$injector
可以解析它们.与#1结合使用时,情况会变得更糟:您可能不知道组件才能提供所有必需的模拟所需的所有依赖关系.
It makes unit test easier. For example you can use the $controller
service to instantiate a controller and feed it with mock objects via the locals
argument. That's certainly easier than having to define a bunch of AngularJS services or factories so that $injector
can resolve them. It becomes worse when coupled with #1: you might not be aware of all dependencies a component needs in order to supply all the necessary mocks.
服务定位器确实提供了一些灵活性思想.例如,您的代码可能仅在服务存在时才使用它,例如:
Service locator does offer some flexibility thought. For example, your code might use a service only if it exists, like this:
if ($injector.has('serviceA')) $injector.get('serviceA').doSomething()
else someSomethingElse()
使用依赖项注入,如果在构造组件时不存在serviceA
,则会出现错误.
With dependency injection, if serviceA
doesn't exist by the time your component is constructed, you'll get an error.
为了便于重构,我认为向构造函数添加/删除参数并不困难.正如您对问题的评论所指出的那样,诸如ngAnnotate
之类的工具将有助于使声明DRYer.
As to ease of refactoring, I don't think it's difficult to add/remove parameters to the constructor function. As pointed out in a comment to your question, tools like ngAnnotate
will help make the declaration DRYer.
因此,我只坚持依赖注入,仅在绝对必要时才使用服务定位器.
Therefore, I would just stick with dependency injection and only use service locator when absolutely necessary.
这篇关于使用$ injector与直接注入服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!