背景
其实 在 publishExternalAPI 里面
function publishExternalAPI(angular){
extend(angular,{
'injector': createInjector ,
})
}
所以 当调用 angular.injector() 的时候 其实是调用的 createInjector 方法
对于 injector 方法
function createInjector(modulesToLoad,strictDi){
// 在这里面 创建了两个 服务$provide $injector
providerCache = {
$provide:{
provider:xxx,
factory:xxx,
service:xxx,
value:xxx,
constant:xxx,
decorator:xxx
}
}
providerInjector = (providerCache.$injector = createInternalInjector(providerCache,function(serviceName,caller) {
//.....
}));
instanceCache = {};
instanceInjector = (instanceCache.$injector = createInternalInjector(instanceCache,function(serviceName,caller){
var provider = providerInjector.get(serviceName + providerSuffix,caller);
return instanceInjector.invoke(provide.$get,provide,undefined,serviceName);
}))
forEach(loadModules(modulesToLoad),function(fn){
if(fn) instanceInjector.invoke(fn);
})
// 最后就返回这个对象了,我们看下这个对象到底有多少东西
{
invoke:function(){},
instantiate:function(){},
get:function(){},
annotate:function(){},
has:function(){}
}
return instanceInjector;
function createInternalInjector(cache,factory){
//....
return {
invoke:invoke,
instantiate:instantiate,
get:getService,
annotate:createInjector.$$annotate,
has:function(name){
turn provideCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
}
}
}
}
对于 createInjector.$$annotate 方法,其实就是
http://my.oschina.net/bosscheng/blog/538462 【如何在javascript中实现DI】
对于坑爹的injector
var $injector = angular.injector(['ng']);
如果不添加参数的话
var injector = angular.injector();
// 这样也能获取到注入器,但是没有和其他模块绑定,相当于创建了一个空的DI容器,里面没有任何服务,所以也没有啥作用
console.log(injector);
console.log(injector.has('$provide')) // false
console.log(injector.has('$injector')) // true
正确的使用: 在创建注入器的时候,需要指定需要加载的模块
var injector = angular.injector(['ng'])// ng 模块是angular 自带的 模块。
// angular.injector 可以调用多次,每次都返回新建的injector对象。
// 所以两次新建的内容可能是不同的
提供的方法有
get
angular.module('myModule', []).
// Teach the injector how to build a 'greeter'
// Notice that greeter itself is dependent on '$window'
factory('greeter', function($window) {
// This is a factory function, and is responsible for
// creating the 'greet' service.
return {
greet: function(text) {
$window.alert(text);
}
};
}).
// New injector is created from the module.
// (This is usually done automatically by angular bootstrap)
var injector = angular.injector('myModule'); // createInjector
// Request any dependency from the injector
var greeter = injector.get('greeter');
// 获取 绑定的model 中的 service 方法。
greeter.greet();
invoke:
直接调用service 中的方法。
对于 invoke 方法的使用 传递的参数 (fn,self,locals,serviceName)
对于内部实现:
内部调用 createInjector.$$annotate(fn,strictDi,serviceName);
后面从service中查找这个service 对象,获取到这个对象之后,获取到这个service
最后 调用fn.apply(self,args); // args 就是真正的 service
injector.invoke(['greeter',function(greeter){
gerrter.greet();
}])
has
injector.has('greeter');
instantiate
create a new instance of js type,the method takes a constructor function, invoke the new
opreator, and supplies all of the arguments to the constructor function as specified by the
constructor annotation.
对于instantiate 的实现
function instantiate(type, locals, serviceName){
// 新建一个对象。
var instance = Object.create((isArray(Type) ? Type[Type.length -1]: Type ).prototype || null);
// 直接执行这个方法
var returnedValue = invoke(Type,instance,locals,serviceName);
return isObject(returnValue) || isFunction(returnedValue) ? returnedValue : instance;
}
annotate
return an array of service names which the function is requesting for injection,this api is
used by the injector to determine which services need to be injected into the function
when the function is invoked .there are three way in which the function can be annotated with the needed dependencies.
大概意思就是,查看这个service,或者controller 所依赖注入的东西。
其实内部就是调用了 createInjector.$$annotate 方法实现的。
注入器负责从我们通过$provider创建的服务中创建注入的实例,只要你编写一个带有可注入性的参数,你能看到注入器是如何工作的,每个angular应用有一个唯一的$injector,当应用启动的时候他被创建出来,你可以通过$injector 注入到任何可注入函数中得到他