diff options
| author | Misko Hevery | 2012-03-23 14:03:24 -0700 |
|---|---|---|
| committer | Misko Hevery | 2012-03-28 11:16:35 -0700 |
| commit | 2430f52bb97fa9d682e5f028c977c5bf94c5ec38 (patch) | |
| tree | e7529b741d70199f36d52090b430510bad07f233 /src/Injector.js | |
| parent | 944098a4e0f753f06b40c73ca3e79991cec6c2e2 (diff) | |
| download | angular.js-2430f52bb97fa9d682e5f028c977c5bf94c5ec38.tar.bz2 | |
chore(module): move files around in preparation for more modules
Diffstat (limited to 'src/Injector.js')
| -rw-r--r-- | src/Injector.js | 516 |
1 files changed, 0 insertions, 516 deletions
diff --git a/src/Injector.js b/src/Injector.js deleted file mode 100644 index 1844db2a..00000000 --- a/src/Injector.js +++ /dev/null @@ -1,516 +0,0 @@ -'use strict'; - -/** - * @ngdoc function - * @name angular.injector - * @function - * - * @description - * Creates an injector function that can be used for retrieving services as well as for - * dependency injection (see {@link guide/dev_guide.di dependency injection}). - * - - * @param {Array.<string|Function>} modules A list of module functions or their aliases. See - * {@link angular.module}. The `ng` module must be explicitly added. - * @returns {function()} Injector function. See {@link angular.module.AUTO.$injector $injector}. - * - * @example - * Typical usage - * <pre> - * // create an injector - * var $injector = angular.injector(['ng']); - * - * // use the injector to kick of your application - * // use the type inference to auto inject arguments, or use implicit injection - * $injector.invoke(function($rootScope, $compile, $document){ - * $compile($document)($rootScope); - * $rootScope.$digest(); - * }); - * </pre> - */ - - -/** - * @ngdoc overview - * @name angular.module.AUTO - * @description - * - * Implicit module which gets automatically added to each {@link angular.module.AUTO.$injector $injector}. - */ - -var FN_ARGS = /^function\s*[^\(]*\(([^\)]*)\)/m; -var FN_ARG_SPLIT = /,/; -var FN_ARG = /^\s*(_?)(.+?)\1\s*$/; -var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; -function inferInjectionArgs(fn) { - assertArgFn(fn); - if (!fn.$inject) { - var args = fn.$inject = []; - var fnText = fn.toString().replace(STRIP_COMMENTS, ''); - var argDecl = fnText.match(FN_ARGS); - forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){ - arg.replace(FN_ARG, function(all, underscore, name){ - args.push(name); - }); - }); - } - return fn.$inject; -} - -/////////////////////////////////////// - -/** - * @ngdoc object - * @name angular.module.AUTO.$injector - * @function - * - * @description - * - * `$injector` is used to retrieve object instances as defined by - * {@link angular.module.AUTO.$provide provider}, instantiate types, invoke methods, - * and load modules. - * - * The following always holds true: - * - * <pre> - * var $injector = angular.injector(); - * expect($injector.get('$injector')).toBe($injector); - * expect($injector.invoke(function($injector){ - * return $injector; - * }).toBe($injector); - * </pre> - * - * # Injection Function Annotation - * - * JavaScript does not have annotations, and annotations are needed for dependency injection. The - * following ways are all valid way of annotating function with injection arguments and are equivalent. - * - * <pre> - * // inferred (only works if code not minified/obfuscated) - * $inject.invoke(function(serviceA){}); - * - * // annotated - * function explicit(serviceA) {}; - * explicit.$inject = ['serviceA']; - * $inject.invoke(explicit); - * - * // inline - * $inject.invoke(['serviceA', function(serviceA){}]); - * </pre> - * - * ## Inference - * - * In JavaScript calling `toString()` on a function returns the function definition. The definition can then be - * parsed and the function arguments can be extracted. *NOTE:* This does not work with minfication, and obfuscation - * tools since these tools change the argument names. - * - * ## `$inject` Annotation - * By adding a `$inject` property onto a function the injection parameters can be specified. - * - * ## Inline - * As an array of injection names, where the last item in the array is the function to call. - */ - -/** - * @ngdoc method - * @name angular.module.AUTO.$injector#get - * @methodOf angular.module.AUTO.$injector - * - * @description - * Return an instance of the service. - * - * @param {string} name The name of the instance to retrieve. - * @return {*} The instance. - */ - -/** - * @ngdoc method - * @name angular.module.AUTO.$injector#invoke - * @methodOf angular.module.AUTO.$injector - * - * @description - * Invoke the method and supply the method arguments from the `$injector`. - * - * @param {!function} fn The function to invoke. The function arguments come form the function annotation. - * @param {Object=} self The `this` for the invoked method. - * @param {Object=} locals Optional object. If preset then any argument names are read from this object first, before - * the `$injector` is consulted. - * @return the value returned by the invoked `fn` function. - */ - -/** - * @ngdoc method - * @name angular.module.AUTO.$injector#instantiate - * @methodOf angular.module.AUTO.$injector - * @description - * Create a new instance of JS type. The method takes a constructor function invokes the new operator and supplies - * all of the arguments to the constructor function as specified by the constructor annotation. - * - * @param {function} Type Annotated constructor function. - * @param {Object=} locals Optional object. If preset then any argument names are read from this object first, before - * the `$injector` is consulted. - * @return new instance of `Type`. - */ - - -/** - * @ngdoc object - * @name angular.module.AUTO.$provide - * - * @description - * - * Use `$provide` to register new providers with the `$injector`. The providers are the factories for the instance. - * The providers share the same name as the instance they create with the `Provider` suffixed to them. - * - * A provider is an object with a `$get()` method. The injector calls the `$get` method to create a new instance of - * a service. The Provider can have additional methods which would allow for configuration of the provider. - * - * <pre> - * function GreetProvider() { - * var salutation = 'Hello'; - * - * this.salutation = function(text) { - * salutation = text; - * }; - * - * this.$get = function() { - * return function (name) { - * return salutation + ' ' + name + '!'; - * }; - * }; - * } - * - * describe('Greeter', function(){ - * - * beforeEach(module(function($provide) { - * $provide.provider('greet', GreetProvider); - * }); - * - * it('should greet', inject(function(greet) { - * expect(greet('angular')).toEqual('Hello angular!'); - * })); - * - * it('should allow configuration of salutation', function() { - * module(function(greetProvider) { - * greetProvider.salutation('Ahoj'); - * }); - * inject(function(greet) { - * expect(greet('angular')).toEqual('Ahoj angular!'); - * }); - * )}; - * - * }); - * </pre> - */ - -/** - * @ngdoc method - * @name angular.module.AUTO.$provide#provider - * @methodOf angular.module.AUTO.$provide - * @description - * - * Register a provider for a service. The providers can be retrieved and can have additional configuration methods. - * - * @param {string} name The name of the instance. NOTE: the provider will be available under `name + 'Provider'` key. - * @param {(Object|function())} provider If the provider is: - * - * - `Object`: then it should have a `$get` method. The `$get` method will be invoked using - * {@link angular.module.AUTO.$injector#invoke $injector.invoke()} when an instance needs to be created. - * - `Constructor`: a new instance of the provider will be created using - * {@link angular.module.AUTO.$injector#instantiate $injector.instantiate()}, then treated as `object`. - * - * @returns {Object} registered provider instance - */ - -/** - * @ngdoc method - * @name angular.module.AUTO.$provide#factory - * @methodOf angular.module.AUTO.$provide - * @description - * - * A short hand for configuring services if only `$get` method is required. - * - * @param {string} name The name of the instance. - * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand for - * `$provide.provider(name, {$get: $getFn})`. - * @returns {Object} registered provider instance - */ - - -/** - * @ngdoc method - * @name angular.module.AUTO.$provide#service - * @methodOf angular.module.AUTO.$provide - * @description - * - * A short hand for registering service of given class. - * - * @param {string} name The name of the instance. - * @param {Function} constructor A class (constructor function) that will be instantiated. - * @returns {Object} registered provider instance - */ - - -/** - * @ngdoc method - * @name angular.module.AUTO.$provide#value - * @methodOf angular.module.AUTO.$provide - * @description - * - * A short hand for configuring services if the `$get` method is a constant. - * - * @param {string} name The name of the instance. - * @param {*} value The value. - * @returns {Object} registered provider instance - */ - - -/** - * @ngdoc method - * @name angular.module.AUTO.$provide#constant - * @methodOf angular.module.AUTO.$provide - * @description - * - * A constant value, but unlike {@link angular.module.AUTO.$provide#value value} it can be injected - * into configuration function (other modules) and it is not interceptable by - * {@link angular.module.AUTO.$provide#decorator decorator}. - * - * @param {string} name The name of the constant. - * @param {*} value The constant value. - * @returns {Object} registered instance - */ - - -/** - * @ngdoc method - * @name angular.module.AUTO.$provide#decorator - * @methodOf angular.module.AUTO.$provide - * @description - * - * Decoration of service, allows the decorator to intercept the service instance creation. The - * returned instance may be the original instance, or a new instance which delegates to the - * original instance. - * - * @param {string} name The name of the service to decorate. - * @param {function()} decorator This function will be invoked when the service needs to be - * instanciated. The function is called using the {@link angular.module.AUTO.$injector#invoke - * injector.invoke} method and is therefore fully injectable. Local injection arguments: - * - * * `$delegate` - The original service instance, which can be monkey patched, configured, - * decorated or delegated to. - */ - - -function createInjector(modulesToLoad) { - var INSTANTIATING = {}, - providerSuffix = 'Provider', - path = [], - loadedModules = new HashMap(), - providerCache = { - $provide: { - provider: supportObject(provider), - factory: supportObject(factory), - service: supportObject(service), - value: supportObject(value), - constant: supportObject(constant), - decorator: decorator - } - }, - providerInjector = createInternalInjector(providerCache, function() { - throw Error("Unknown provider: " + path.join(' <- ')); - }), - instanceCache = {}, - instanceInjector = (instanceCache.$injector = - createInternalInjector(instanceCache, function(servicename) { - var provider = providerInjector.get(servicename + providerSuffix); - return instanceInjector.invoke(provider.$get, provider); - })); - - - forEach(loadModules(modulesToLoad), function(fn) { instanceInjector.invoke(fn || noop); }); - - return instanceInjector; - - //////////////////////////////////// - // $provider - //////////////////////////////////// - - function supportObject(delegate) { - return function(key, value) { - if (isObject(key)) { - forEach(key, reverseParams(delegate)); - } else { - return delegate(key, value); - } - } - } - - function provider(name, provider_) { - if (isFunction(provider_)) { - provider_ = providerInjector.instantiate(provider_); - } - if (!provider_.$get) { - throw Error('Provider ' + name + ' must define $get factory method.'); - } - return providerCache[name + providerSuffix] = provider_; - } - - function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); } - - function service(name, constructor) { - return factory(name, ['$injector', function($injector) { - return $injector.instantiate(constructor); - }]); - } - - function value(name, value) { return factory(name, valueFn(value)); } - - function constant(name, value) { - providerCache[name] = value; - instanceCache[name] = value; - } - - function decorator(serviceName, decorFn) { - var origProvider = providerInjector.get(serviceName + providerSuffix), - orig$get = origProvider.$get; - - origProvider.$get = function() { - var origInstance = instanceInjector.invoke(orig$get, origProvider); - return instanceInjector.invoke(decorFn, null, {$delegate: origInstance}); - }; - } - - //////////////////////////////////// - // Module Loading - //////////////////////////////////// - function loadModules(modulesToLoad){ - var runBlocks = []; - forEach(modulesToLoad, function(module) { - if (loadedModules.get(module)) return; - loadedModules.put(module, true); - if (isString(module)) { - var moduleFn = angularModule(module); - runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks); - - try { - for(var invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) { - var invokeArgs = invokeQueue[i], - provider = invokeArgs[0] == '$injector' - ? providerInjector - : providerInjector.get(invokeArgs[0]); - - provider[invokeArgs[1]].apply(provider, invokeArgs[2]); - } - } catch (e) { - if (e.message) e.message += ' from ' + module; - throw e; - } - } else if (isFunction(module)) { - try { - runBlocks.push(providerInjector.invoke(module)); - } catch (e) { - if (e.message) e.message += ' from ' + module; - throw e; - } - } else if (isArray(module)) { - try { - runBlocks.push(providerInjector.invoke(module)); - } catch (e) { - if (e.message) e.message += ' from ' + String(module[module.length - 1]); - throw e; - } - } else { - assertArgFn(module, 'module'); - } - }); - return runBlocks; - } - - //////////////////////////////////// - // internal Injector - //////////////////////////////////// - - function createInternalInjector(cache, factory) { - - function getService(serviceName) { - if (typeof serviceName !== 'string') { - throw Error('Service name expected'); - } - if (cache.hasOwnProperty(serviceName)) { - if (cache[serviceName] === INSTANTIATING) { - throw Error('Circular dependency: ' + path.join(' <- ')); - } - return cache[serviceName]; - } else { - try { - path.unshift(serviceName); - cache[serviceName] = INSTANTIATING; - return cache[serviceName] = factory(serviceName); - } finally { - path.shift(); - } - } - } - - function invoke(fn, self, locals){ - var args = [], - $inject, - length, - key; - - if (typeof fn == 'function') { - $inject = inferInjectionArgs(fn); - length = $inject.length; - } else { - if (isArray(fn)) { - $inject = fn; - length = $inject.length - 1; - fn = $inject[length]; - } - assertArgFn(fn, 'fn'); - } - - for(var i = 0; i < length; i++) { - key = $inject[i]; - args.push( - locals && locals.hasOwnProperty(key) - ? locals[key] - : getService(key, path) - ); - } - - // Performance optimization: http://jsperf.com/apply-vs-call-vs-invoke - switch (self ? -1 : args.length) { - case 0: return fn(); - case 1: return fn(args[0]); - case 2: return fn(args[0], args[1]); - case 3: return fn(args[0], args[1], args[2]); - case 4: return fn(args[0], args[1], args[2], args[3]); - case 5: return fn(args[0], args[1], args[2], args[3], args[4]); - case 6: return fn(args[0], args[1], args[2], args[3], args[4], args[5]); - case 7: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - case 8: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); - case 9: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); - case 10: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); - default: return fn.apply(self, args); - } - } - - function instantiate(Type, locals) { - var Constructor = function() {}, - instance, returnedValue; - - Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Type).prototype; - instance = new Constructor(); - returnedValue = invoke(Type, instance, locals); - - return isObject(returnedValue) ? returnedValue : instance; - } - - return { - invoke: invoke, - instantiate: instantiate, - get: getService - }; - } -} |
