[英]Is there any downside to using $injector.get() to get my dependencies in Angular?
My team wants to move to a style of dependency injection that is closer to the CommonJS/Node JS syntax for out Angular codebase: 我的团队想要转向一种依赖注入的样式,这种注入更接近用于Angular代码库的CommonJS / Node JS语法:
var myDependency = require('myDependency');
I've started using $injector.get()
directly inside at the top of my functions, so far with no obvious trouble. 我已经开始直接在函数顶部使用
$injector.get()
,到目前为止,没有明显的麻烦。 That means I've converted this: 这意味着我已经将其转换为:
angular.module('modD', ['modA', 'modB', 'modC'])
.service('serviceD', ['serviceA', 'serviceB', 'serviceC', function(serviceA, serviceB, serviceC) {
//My code here
}])
Into: 进入:
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
}]);
Is there something I'm missing. 有什么我想念的吗? Does not declaring the required dependencies outside of the function definition cause any sort of performance issues?
在函数定义之外声明所需的依赖项是否会导致任何类型的性能问题?
Note: this answer has not been tested. 注意:此答案尚未测试。 After digging into the angular's code, I find this:
在探究了angular的代码之后,我发现了这一点:
// 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);
}
};
Its calls seems like: 它的调用看起来像:
service
invoked factory
invoked instantiate
service
调用factory
调用instantiate
factory
invoked provider
invoked instantiate
factory
调用provider
调用instantiate
So I think your questions is equal to Is calling $injector.get() one by one has the same performance as calling $injector.instantiate() once? 因此,我认为您的问题等同于一次调用$ injector.get()与调用一次$ injector.instantiate()具有相同的性能吗?
As the code shows, instantiate
invoked invoke
which actually invoked getService
for each services injected by you. 如代码所示,
instantiate
被invoke
,它实际上为您注入的每个服务调用了getService
。 And $injector.get
is just binding to getService
. $injector.get
只是绑定到getService
。
So the answer to my equal question is True . 因此,对我同样的问题的回答是“对” 。
And the answer to your question is No, their performance is very close . 您的问题的答案是否定的,他们的表现非常接近 。
Please correct me if I'm wrong, thank you! 如果我错了,请指正我,谢谢!
There are no significant difference between both pieces of code in the case of a service. 在服务的情况下,这两段代码之间没有显着差异。
$injector.get(...)
call doesn't provide any overhead. $injector.get(...)
调用不会产生任何开销。 But it provides a significant amount of extra characters per dependency. 但是它为每个依赖项提供了大量额外的字符。
There is a difference when the same thing is done with injectables that have local dependencies - controllers and route/state resolvers. 当对具有局部依赖项的可注射对象执行相同的操作时,会有所不同-控制器和路由/状态解析器。
When these dependencies 当这些依赖
app.controller('SomeCtrl', function ($scope, service) { ... });
are replaced with $injector.get(...)
, it will choke on $scope
- it is local dependency. 被
$injector.get(...)
替换,它将阻塞$scope
它是本地依赖项。 And with other dependencies being retrieved like that, controller loses its testability. 像这样检索其他依赖项,控制器将失去其可测试性。 The dependencies cannot be mocked with
依赖关系不能被模拟
$controller('SomeCtrl', { service: mockedService });
I personally don't see how $injector.get(...)
may benefit the style of the project (and haven't seen a good style guide that would suggest it). 我个人没有看到
$injector.get(...)
如何使项目的样式受益(也没有看到一个好的样式指南对此有所建议)。
Node uses require
function because it works for it, not because it is better or cooler. 节点使用
require
函数是因为它起作用,而不是因为它更好或更凉。 The alternative would be to pack each Node script into into AMD-like wrappers, which would be painful. 另一种选择是将每个Node脚本打包到类似AMD的包装中,这将很痛苦。 Fortunately, we already have wrappers around Angular units!
幸运的是,我们已经在Angular单元周围有了包装器!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.