[AngularJS面面观] 20. 依赖注入 --- instance注入器以及provide
本文就来解答上一篇文章留下的疑问,为什么在注入器也分成了 总体结构为此我特别准备了一张图来描述一下angular注入器的工作流程和原理,如下所示。 这张图的顶部是外部调用的入口,即通过angular暴露给外部的 那么暴露给外部使用的 instance注入器instanceCache = {},protoInstanceInjector =
createInternalInjector(instanceCache,function(serviceName,caller) {
var provider = providerInjector.get(serviceName + providerSuffix,caller);
return instanceInjector.invoke(
provider.$get,provider,undefined,serviceName);
}),instanceInjector = protoInstanceInjector;
// createInternalInjector的函数签名
function createInternalInjector(cache,factory) {
// ......
}
// factory在getService函数中被用到
function getService(serviceName,caller) {
if (cache.hasOwnProperty(serviceName)) {
if (cache[serviceName] === INSTANTIATING) {
throw $injectorMinErr('cdep','Circular dependency found: {0}',serviceName + ' <- ' + path.join(' <- '));
}
return cache[serviceName];
} else {
try {
path.unshift(serviceName);
cache[serviceName] = INSTANTIATING;
// 注意下面这一行代码的行为,调用factory得到实例然后保存并返回
return cache[serviceName] = factory(serviceName,caller);
} catch (err) {
if (cache[serviceName] === INSTANTIATING) {
delete cache[serviceName];
}
throw err;
} finally {
path.shift();
}
}
}
注入器本身的实例是通过调用 那让我们来看看实例注入器是如何声明这个 // providerSuffix实际上就是一个字符串:Provider
var providerSuffix = 'Provider';
createInternalInjector(instanceCache,caller) {
var provider = providerInjector.get(serviceName + providerSuffix,caller);
return instanceInjector.invoke(provider.$get,serviceName);
}),
很明显的是,在实例注入器的 provider注入器简要分析了实例注入器之后,下面来看看另一个主角 - providerCache = {
$provide: {
provider: supportObject(provider),factory: supportObject(factory),service: supportObject(service),value: supportObject(value),constant: supportObject(constant),decorator: decorator
}
},providerInjector = (providerCache.$injector =
createInternalInjector(providerCache,caller) {
if (angular.isString(caller)) {
path.push(caller);
}
throw $injectorMinErr('unpr',"Unknown provider: {0}",path.join(' <- '));
}));
首先, 然后还是通过 另外值得一提的是,在创建了实例注入器和 providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };
// valueFn的定义
function valueFn(value) {return function valueRef() {return value;};}
它将实例注入器的通过 为什么要这样实现看清楚了angular注入器的实现原理和流程,我们来思考一下为什么它会这么设计。这个问题也许只有开发这个功能的人才能最终解释清楚。但是这一点是很明显的: 隐藏不必要的信息,将功能的入口单一化。也就是所谓的门面模式(Facade Pattern)。这个门面就是angular中的 但是学习angular中注入器的设计和实现也是一件非常有意思的事情,真的是开拓了眼界。一个框架的重要功能原来是这么实现的,一点一点地去分析去思考也是能够看懂背后的逻辑的,毕竟再复杂的程序也是一行一行代码垒起来的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 手指的位置,以提高Vim的生产力
- openldap – nss_ldap:无法搜索LDAP服务器 – 服务器不可用
- 如何将变量从文本文件变成Bash变量
- angular – FormArray TypeError:value.forEach不是函数
- vim YouCompleteMe unknown function pythoncomplete#compl
- docker-ce:取决于:libseccomp2(> = 2.3.0)但是要安装
- 根据公司需求写的一个linux 巡检小脚本
- Linux 中纠正拼写错误的Bash 命令方法
- 有没有办法从Scala中的数组或List初始化多个变量?
- 角度2形式分布在各个组件上