背景 javascript
其實 在 publishExternalAPI 裏面
java
function publishExternalAPI(angular){ extend(angular,{ 'injector': createInjector , }) }
因此 當調用 angular.injector() 的時候 實際上是調用的 createInjector 方法bootstrap
對於 injector 方法c#
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 方法,其實就是api
http://my.oschina.net/bosscheng/blog/538462 【如何在javascript中實現DI】app
對於坑爹的injector ide
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
正確的使用: 在建立注入器的時候,須要指定須要加載的模塊ui
var injector = angular.injector(['ng'])// ng 模塊是angular 自帶的 模塊。 // angular.injector 能夠調用屢次,每次都返回新建的injector對象。 // 因此兩次新建的內容多是不一樣的
提供的方法有this
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 注入到任何可注入函數中獲得他