angular之$injector

背景 

    其实 在 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 注入到任何可注入函数中得到他





转载于:https://my.oschina.net/bosscheng/blog/512388

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值