使用$ injector.get()来获取Angular中的依赖项有什么缺点吗?

时间:2016-08-21 00:10:00

标签: javascript angularjs dependency-injection

我的团队想要转向一种依赖注入的风格,它更接近于用于Angular代码库的CommonJS / Node JS语法:

var myDependency = require('myDependency');

我已经开始在我的函数顶部直接使用$injector.get(),到目前为止没有明显的麻烦。这意味着我已将此转换为:

angular.module('modD', ['modA', 'modB', 'modC'])
.service('serviceD', ['serviceA', 'serviceB', 'serviceC', function(serviceA, serviceB, serviceC) {
  //My code here
}])

分为:

angular.module('modD', ['modA', 'modB', 'modC'])
.service('serviceD', ['$injector', function($injector) {
  var serviceA = $injector.get('serviceA');
  var serviceB = $injector.get('serviceB');
  var serviceC = $injector.get('serviceC');

  //My code here
}]);

我有什么遗失的东西。不在函数定义之外声明所需的依赖项会导致任何类型的性能问题吗?

2 个答案:

答案 0 :(得分:1)

注意:此答案尚未经过测试。 在深入了解角度代码之后,我发现了这个:

style="@android:style/Widget.Holo.Light.RatingBar.Small

它的电话似乎是:

  • // in function createInjector function provider(name, provider_) { ... if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ... return providerCache[name + providerSuffix] = provider_; } ... function factory(name, factoryFn, enforce) { return provider(name, { $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn }); } function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); } ... // in function createInternalInjector function invoke (...){ ... for (i = 0, length = $inject.length; i < length; i++) { args.push( locals && locals.hasOwnProperty(key) ? locals[key] : getService(key, serviceName) ); } ... return fn.apply(self, args); } function instantiate(...){ ... var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype || null); var returnedValue = invoke(Type, instance, locals, serviceName); return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance; } ... return { invoke: invoke, instantiate: instantiate, get: getService, annotate: createInjector.$$annotate, has: function(name) { return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name); } }; 已调用service调用了factory
  • instantiate已调用factory调用了provider

所以我认为你的问题等于逐个调用$ injector.get()与调用$ injector.instantiate()一次具有相同的性能吗?

如代码所示,instantiate调用了instantiate,它为您注入的每个服务实际调用了invoke。而getService只是绑定到$injector.get

所以我的平等问题的答案是 True

你问题的答案是不,他们的表现非常接近

如果我错了,请纠正我,谢谢!

答案 1 :(得分:1)

在服务的情况下,两段代码之间没有显着差异。 $injector.get(...)电话不会提供任何开销。但它为每个依赖提供了大量额外的字符。

对于具有本地依赖关系的注入事项(控制器和路由/状态解析器),同样的事情会有所不同。

当这些依赖

app.controller('SomeCtrl', function ($scope, service) { ... });

替换为$injector.get(...),它会阻塞$scope - 它是本地依赖项。并且,如此检索其他依赖项,控制器将失去其可测试性。无法使用

模拟依赖项
$controller('SomeCtrl', { service: mockedService });

我个人并不知道$injector.get(...)如何对项目的风格有所帮助(而且还没有看到一个好的风格指南)。

节点使用require函数,因为它适用于它,而不是因为它更好或更酷。另一种方法是将每个Node脚本打包成类似AMD的包装器,这将是痛苦的。幸运的是,我们已经有了围绕Angular单位的包装器!