3

Edit 04/15 The answers I've gotten so far explain the difference between service/factory/ and provider, but that doesn't really get at what I'm confused about. AngularJS documentation asserts that all three are essentially the same code "under the hood". But if that's the case, why can I only pass a "provider" into a configuration block, as opposed to a "factory"?

Original Question:

According to the documentation for Providers:

The most verbose, but also the most comprehensive one is a Provider recipe. The remaining four recipe types — Value, Factory, Service and Constant — are just syntactic sugar on top of a provider recipe.

That gives me the impression that all services are also providers. But I'm currently dealing with a problem using the $window service in my app's configuration block, and came across this bit of documentation:

Module Loading & Dependencies

A module is a collection of configuration and run blocks which get applied to the application during the bootstrap process. In its simplest form the module consist of a collection of two kinds of blocks:

  • Configuration blocks - get executed during the provider registrations and configuration phase. Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured.

Which implies there's a distinction between a provider and a service that's more fundamental than a service recipe simply being "syntactic sugar" over the provider recipe. What's the deal?

BobbyA
  • 2,090
  • 23
  • 41
  • The point is that service is instance. http://stackoverflow.com/questions/15666048/service-vs-provider-vs-factory/15666049#15666049 – ABOS Apr 13 '15 at 22:37

2 Answers2

1

A provider is a factory that instantiates a service via its $get method. Providers are used to configure a service before the application gets going by being available in a module's config phase.

A service is simply an injected singleton. You can define a service by:

  • Calling myModule.service('serviceName', ServiceConstructor), where ServiceConstructor is a constructor you would normally use new with.
  • Calling myModule.factory('serviceName', factoryFunction), where factoryFunction is a function that returns the service instance.
  • Calling myModule.value('serviceName', serviceInstance), where serviceInstance is the actual thing that will be injected
  • Calling myModule.provider('serviceName', serviceProvider), where serviceProvider is some object with a $get method that returns the service instance.
Jeremy Elbourn
  • 2,630
  • 1
  • 18
  • 15
0

basically what happens is

when you make a factory() it sets you function provided in second argument to provider's $get and return it(provider(name, {$get:factoryFn })), all you get is provider but no property/method other then $get of that provider(means you cant configure this)

source of factory

function factory(name, factoryFn, enforce) {
    return provider(name, {
      $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
    });
  }

when making a service() it return you providing a factory() with a function that injects the constructor (return the instance of the constructor you provided in your service) and returns it

source code of service

function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
  }

So basically in both cases you eventually get a providers $get set to your function you provided , but you can give anything extra than $get as you can originally provide in provider() for config block

A.B
  • 20,110
  • 3
  • 37
  • 71