diff options
Diffstat (limited to 'src/Injector.js')
| -rw-r--r-- | src/Injector.js | 251 |
1 files changed, 225 insertions, 26 deletions
diff --git a/src/Injector.js b/src/Injector.js index 58b30fda..fbc6d3a0 100644 --- a/src/Injector.js +++ b/src/Injector.js @@ -9,37 +9,35 @@ * 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}). * - * Creating an injector doesn't automatically create all of the `$eager` - * {@link angular.service services}. You have to call `injector.eager()` to initialize them. - * - * @param {Object.<string, function()>=} [factories=angular.service] Map of the service factory - * functions. - * @returns {function()} Injector function: - * - * * `injector(serviceName)`: - * * `serviceName` - `{string=}` - Name of the service to retrieve. - * - * The injector function also has these properties: - * - * * An `invoke` property which can be used to invoke methods with dependency-injected arguments. - * `injector.invoke(self, fn, locals)` - * * `self` - The "`this`" to be used when invoking the function. - * * `fn` - The function to be invoked. The function may have the `$inject` property that - * lists the set of arguments which should be auto-injected. - * (see {@link guide/dev_guide.di dependency injection}). - * * `locals(array)` - Optional array of arguments to pass to the function - * invocation after the injection arguments. - * * An `eager` property which is used to initialize the eager services. - * `injector.eager()` + + * @param {<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(function($rootScope, $compile, $document){ + * $compile($document)($rootScope); + * $rootScope.$digest(); + * }); + * </pre> */ /** - * @returns the $inject property of function. If not found the - * the $inject is computed by looking at the toString of function and - * extracting all arguments which and assuming that they are the - * injection names. + * @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*(.+?)\s*$/; @@ -60,6 +58,207 @@ function inferInjectionArgs(fn) { } /////////////////////////////////////// + +/** + * @ngdoc function + * @name angular.module.AUTO.$injector + * @function + * + * @description + * + * `$injector` function is used to retrieve object instances. Object instances are defined by + * {@link angular.module.AUTO.$provide provider}. + * + * The following always holds true: + * + * <pre> + * var $injector = angular.injector(); + * expect($injector('$injector')).toBe($injector); + * expect($injector(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. + * + * @param {string, function()} argument If the `argument` is: + * + * - `string`: Retrieve an instance of a named object. If object does not exist, use the provider to create + * a new instance. Calling the method repeatedly with the same name will always return the same + * instance. + * - `function`: Invoke the function. This is a short hand for `$injector.`{@link #invoke invoke(null, argument)}. + * @return the object instance or the return value of the invoked function. + */ + +/** + * @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 {Object} self The `this` for the invoked method. + * @param {function} fn The function to invoke. The function arguments come form the function annotation. + * @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 method + * @name angular.module.AUTO.$injector#loadModule + * @methodOf angular.module.AUTO.$injector + * @description + * Load additional modules into the current injector configuration + * + * @param {Array} modules An array of modules, where module is a: + * + * - `string`: look up the module function from {@link angular.module} and then treat as `function`. + * - `function`: execute the module configuration function using + * {@link angular.module.AUTO.$injector#invoke $injector.invoke()} + */ + + + +/** + * @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 `Provide` 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(inject(function($provide) { + * $provide.service('greet', GreetProvider); + * }); + * + * it('should greet', inject(function(greet) { + * expect(greet('angular')).toEqual('Hello angular!'); + * })); + * + * it('should allow configuration of salutation', inject( + * function(greetProvider) { + * greetProvider.salutation('Ahoj'); + * }, + * function(greet) { + * expect(greet('angular')).toEqual('Ahoj angular!'); + * } + * )}; + * + * }); + * </pre> + */ + +/** + * @ngdoc method + * @name angular.module.AUTO.$provide#service + * @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 + 'Provide'` 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`. + * + */ + +/** + * @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. NOTE: the provider will be available under `name + 'Provide'` key. + * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand for + * `$provide.service(name, {$get:$getFn})`. + */ + + +/** + * @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. NOTE: the provider will be available under `name + 'Provide'` key. + * @param {function()} value The $getFn for the instance creation. Internally this is a short hand for + * `$provide.service(name, {$get:function(){ return value; }})`. + */ + + function createInjector(modulesToLoad, moduleRegistry) { var cache = {}, $injector = internalInjector(cache), |
