Improve this doc

Angular allows services to declare other services as dependencies needed for construction of their instances.

To declare dependencies, you specify them in the factory function signature and annotate the function with the inject annotations either using by setting the $inject property, as an array of string identifiers or using the array notation. Optionally the $inject property declaration can be dropped (see "Inferring $inject" but note that that is currently an experimental feature).

Using the array notation:

  1. function myModuleCfgFn($provide) {
  2. $provide.factory('myService', ['dep1', 'dep2', function(dep1, dep2) {}]);
  3. }

Using the $inject property:

  1. function myModuleCfgFn($provide) {
  2. var myServiceFactory = function(dep1, dep2) {};
  3. myServiceFactory.$inject = ['dep1', 'dep2'];
  4. $provide.factory('myService', myServiceFactory);
  5. }

Using DI inference (incompatible with minifiers):

  1. function myModuleCfgFn($provide) {
  2. $provide.factory('myService', function(dep1, dep2) {});
  3. }

Here is an example of two services, one of which depends on the other and both of which depend on other services that are provided by the Angular framework:

  1. /**
  2. * batchLog service allows for messages to be queued in memory and flushed
  3. * to the console.log every 50 seconds.
  4. *
  5. * @param {*} message Message to be logged.
  6. */
  7. function batchLogModule($provide){
  8. $provide.factory('batchLog', ['$timeout', '$log', function($timeout, $log) {
  9. var messageQueue = [];
  10.  
  11. function log() {
  12. if (messageQueue.length) {
  13. $log('batchLog messages: ', messageQueue);
  14. messageQueue = [];
  15. }
  16. $timeout(log, 50000);
  17. }
  18.  
  19. // start periodic checking
  20. log();
  21.  
  22. return function(message) {
  23. messageQueue.push(message);
  24. }
  25. }]);
  26.  
  27. /**
  28. * routeTemplateMonitor monitors each $route change and logs the current
  29. * template via the batchLog service.
  30. */
  31. $provide.factory('routeTemplateMonitor',
  32. ['$route', 'batchLog', '$rootScope',
  33. function($route, batchLog, $rootScope) {
  34. $rootScope.$on('$routeChangeSuccess', function() {
  35. batchLog($route.current ? $route.current.template : null);
  36. });
  37. }]);
  38. }
  39.  
  40. // get the main service to kick of the application
  41. angular.injector([batchLogModule]).get('routeTemplateMonitor');

Things to notice in this example:

  • The batchLog service depends on the built-in $timeout and $log services, and allows messages to be logged into the console.log in batches.
  • The routeTemplateMonitor service depends on the built-in $route service as well as our custom batchLog service.
  • Both of our services use the factory function signature and array notation for inject annotations to declare their dependencies. It is important that the order of the string identifiers in the array is the same as the order of argument names in the signature of the factory function. Unless the dependencies are inferred from the function signature, it is this array with IDs and their order that the injector uses to determine which services and in which order to inject.

Related Topics

Related API