@workInProgress @ngdoc overview @name angular.service @description # Overview Services are substituable objects, which are wired together using dependency injection (DI). Each service could have dependencies (other services), which are passed in constructor. Because JS is dynamicaly typed language, dependency injection can not use static types to identify these dependencies, so each service must explicitely define its dependencies. This is done by `$inject` property. # Built-in services angular provides a set of services for common operations. These services can be overriden by custom services if needed. Like other core angular variables and identifiers, the built-in services always start with `$`. * {@link angular.service.$browser $browser} * {@link angular.service.$window $window} * {@link angular.service.$document $document} * {@link angular.service.$location $location} * {@link angular.service.$log $log} * {@link angular.service.$exceptionHandler $exceptionHandler} * {@link angular.service.$hover $hover} * {@link angular.service.$invalidWidgets $invalidWidgets} * {@link angular.service.$route $route} * {@link angular.service.$xhr $xhr} * {@link angular.service.$xhr.error $xhr.error} * {@link angular.service.$xhr.bulk $xhr.bulk} * {@link angular.service.$xhr.cache $xhr.cache} * {@link angular.service.$resource $resource} * {@link angular.service.$cookies $cookies} * {@link angular.service.$cookieStore $cookieStore} # Writing your own custom services angular provides only set of basic services, so for any nontrivial application it will be necessary to write one or more custom services. To do so, a factory function that creates a services needs to be registered with angular's dependency injector. This factory function must return an object - the service (it is not called with the `new` operator). **angular.service** accepts three parameters: - `{string} name` - Name of the service. - `{function()} factory` - Factory function (called just once by DI). - `{Object} config` - Configuration object with following properties: - `$inject` - {Array.} - Array of service ids that this service depends on. These services will be passed as arguments into the factory function in the same order as specified in the `$inject` array. Defaults to `[]`. - `$eager` - {boolean} - If true, the service factory will be called and thus, the service will be instantiated when angular boots. If false, service will be lazily instantiated when it is first requested during instantiation of a dependant. Defaults to `false`. The `this` of the factory function is bound to the root scope of the angular application. angular enables services to participate in dependency injection (DI) by registering themselves with angular's DI system (injector) under a `name` (id) as well as by declaring dependencies which need to be provided for the factory function of the registered service. The ability to swap dependencies for mocks/stubs/dummies in tests allows for services to be highly testable. Here is an example of very simple service. This service requires $window service (it's passed as a parameter to factory function) and it's just a function. This service simple stores all notifications and after third one, it displays all of them by window alert.
       angular.service('notify', function(win) {
         var msgs = [];
         return function(msg) {
           msgs.push(msg);
           if (msgs.length == 3) {
             win.alert(msgs.join("\n"));
             msgs = [];
           }
         };
       }, {$inject: ['$window']});
And here is a unit test for this service. We use Jasmine spy (mock) instead of real browser's alert.
var mock, notify;

beforeEach(function() {
  mock = {alert: jasmine.createSpy()};
  notify = angular.service('notify')(mock);
});

it('should not alert first two notifications', function() {
  notify('one');
  notify('two');
  expect(mock.alert).not.toHaveBeenCalled();
});

it('should alert all after third notification', function() {
  notify('one');
  notify('two');
  notify('three');
  expect(mock.alert).toHaveBeenCalledWith("one\ntwo\nthree");
});

it('should clear messages after alert', function() {
  notify('one');
  notify('two');
  notify('third');
  notify('more');
  notify('two');
  notify('third');
  expect(mock.alert.callCount).toEqual(2);
  expect(mock.alert.mostRecentCall.args).toEqual(["more\ntwo\nthird"]);
});
# Injecting services into controllers Using services as dependencies for controllers is very similar to using them as dependencies for another service. JavaScript is dynamic language, so DI is not able to figure out which services to inject by static types (like in static typed languages). Therefore you must specify the service name by the `$inject` property - it's an array that contains strings with names of services to be injected. The name must match the id that service has been registered as with angular. The order of the services in the array matters, because this order will be used when calling the factory function with injected parameters. The names of parameters in factory function don't matter, but by convention they match the service ids.
function myController($loc, $log) {
  this.firstMethod = function() {
    // use $location service
    $loc.setHash();
  };
  this.secondMethod = function() {
    // use $log service
    $log.info('...');
  };
}
// which services to inject ?
myController.$inject = ['$location', '$log'];
@example

Let's try this simple notify service, injected into the controller...

it('should test service', function(){ expect(element(':input[name=message]').val()).toEqual('test'); });