使用$ injector vs直接注入服务

时间:2014-11-23 22:37:02

标签: angularjs

我想知道你何时会使用$injector.get('someService') vs直接注入该服务。

基本上,下面两个代码的区别是什么?

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它会更容易添加/删除依赖项。

1 个答案:

答案 0 :(得分:6)

第一种方法使用依赖注入,而第二种方法使用服务定位器模式。依赖注入具有以下优点:

  • 它使组件的依赖关系显式化。例如,您可以查看控制器的构造函数,并立即知道它需要哪些依赖项。使用服务定位器,您通常不知道,因为控制器可能随时调用服务定位器。

  • 它使单元测试更容易。例如,您可以使用$controller服务来实例化控制器,并通过locals参数向模拟对象提供它。这比定义一堆AngularJS服务或工厂更容易,以便$injector可以解决它们。与#1结合使用会变得更糟:您可能不知道组件需要的所有依赖项,以便提供所有必要的模拟。

服务定位器确实提供了一些灵活性。例如,您的代码可能仅在存在时使用服务,如下所示:

if ($injector.has('serviceA')) $injector.get('serviceA').doSomething() 
else someSomethingElse()

使用依赖项注入,如果在构建组件时serviceA不存在,则会出现错误。

至于重构的简易性,我认为在构造函数中添加/删除参数很困难。正如您对问题的评论所指出的那样,像ngAnnotate这样的工具将有助于使声明DRYer。

因此,我会坚持依赖注入,只在绝对必要时使用服务定位器。