by Jeremy Mason

Combines related components of your application
into a single, reusable component
angular.module('myModule', ['dep1', 'dep2']);
angular.module('myModule');
// Order of execution matters!
// This fails if module has not been declared yet
angular.module('myModule')
    .config(function () { ... })
    .run(function () { ... })More on this later...Custom objects that are shared across your application
function MyService($http) {
    ...
};
angular.module('myModule')
    .service('$myService', MyService);
    function MyService($http) {
    ...
};
angular.module('myModule')
    .service('$myService', ['$http', MyService]);function MyService($http) {
    ...
};
MyService.$inject = ['$http'];
angular.module('myModule')
    .service('$myService', MyService);$injector.invoke(function (dep) { ... });var injector = angular.injector(['ng', 'mod1']);
angular.module('api')
    .constant('$apiKey', '1234567890abcdef');function PersonService($http) {
    this.create = function (info) {
        return $http.post('/api/person', info);
    };
}
angular.module('api')
    .service('$person', PersonService);angular.module('api')
    .factory('$person', function ($http) {
        return {
            create: function (info) {
                return $http.post('/api/person', info);
            }
        };
    });angular.module('api')
    .provider('$person', function () {
        return {
            $get: function ($http) {
                return {
                    create: function (info) {
                        return $http.post('/api/person', info);
                    }
                };
            }
        };
    });$myService, $myServiceProvider
// Fail!
angular.module('...')
    .config(function ($myService) { ... });
    
// OK!
angular.module('...')
    .config(function ($myServiceProvider) { ... });
    
angular.module('...')
    .run(function ($myService) { ... });
    
angular.module('...')
    .run(function ($myServiceProvider) { ... });angular.module('api')
    .provider('$person', function () {
        var personCache = { };
        var provider = { cache: false };
        
        provider.$get = function ($q, http) {
            return {
                fetch: function (id) {
                    
                    if (provider.cache && personCache[id]) {
                        return $q.when(personCache[id]);
                    }
                    
                    return $http.get('/api/persons/' + id)
                        .then(function (result) {
                            
                            if (provider.cache) {
                                personCache[id] = result.data;
                            }
                            
                            return result.data;
                        });
                }
            };
        };
        
        return provider;
    });
    
angular.module('myApp')
    .config(function ($personProvider) {
        $personProvider.cache = true;
    });angular.module('api')
    .decorator('$person', function ($delegate) {
        var newInstance = {};
        
        // ...
        
        return newInstance;
    });angular.module('api')
    .decorator('$person', function ($q, $delegate) {
        var personCache = {};
        
        var fetch = $delegate.fetch;
        $delegate.fetch = function (id) {
            if (personCache[id]) {
                return $q.when(personCache[id]);
            }
            
            return fetch(id);
        };
        
        return $delegate;
    });angular.module('api')
    .decorator('$person', function ($q, $delegate) {
        var personCache = {};
        
        return {
            fetch: function (id) {
                if (personCache[id]) {
                    return $q.when(personCache[id]);
                }
                
                return $delegate.fetch(id);
            }
        };
    });function CreatePersonCtrl($scope, $person) {
    $scope.model = {};
    
    $scope.create = function () {
        var info = {
            FirstName: $scope.model.firstName;
            LastName: $scope.model.lastName;
        };
        
        $person.create(info)
            .then(...);
    };
}
angular.module('app')
    .controller('CreatePersonCtrl', CreatePersonCtrl);