Unit 3 Notes (part 1 – DI) from Yakov Fain online Angular training, spring 2016

Dependency Injection (DI)

Interesting discussion around 1 minute mark of Unit 3

There are various problems with newing up an  instance of an object and passing it into a constructor or other method. (a) The code of the object may not be ready and (b) newing up mock objects is helpful, but can still create unneeded complications.

DI is preferred because:

  • The app is not responsible for creating the objects.
  • Angular 2 will create and ‘inject’ objects into application components.
  • Replacing an inject-able object is just a configuration change.
  • DI addresses loos coupling and re-usability
  • Useful for testing

To use DI, include one or more providers on the @Component decorator of a component:

@Component ({
   (other stuff) 
   providers: [ProductService]

export default class ProductComponent {
    product: Product;
    constructor { productService: ProductService) {
        this.product = ProductService.getProduct();

This is the simpler of the two notations one can use. It basically says to Angular 2 ‘Provide me with an instance of this type when this component or one of its children has an argument of type ‘ProductService’ in one of its constructors.’

Note that one instance of ProviderServices will be instantiated each time the ProductComponent constructor is called. Depending on the app, this could be just once, or many times. So, one or many instances of ProviderServices can be created. it depends on how the app is designed.

A child component can override an ancestor’s provider(s) by having its own providers array on its @Component decorator.

Key: To use a different service, say a mock service, one need only change the value(s) in the providers array on the @Component decorator:

 providers: [MockProductService]

Angular 2 DI:

  • Injects objects into components only via constructors
  • Each component has its own injector 
  • Providers specify how to inject
  • A provider can be specified on a component or one of its ancestors. (If an object has no instance of the object to be injected, Angular 2 checks its parent and, if need be, other ancestors.)

Injectors & Providers

  • Providers tell Angular 2 how to make an instance.
  • Providers allow you to map a token to a concrete implementation of the type – typically this token will be a type:
    • The first argument, in this case ‘ProductService’, is the token:
      providers: [provide(ProductService, {useclass:ProductService})];

      Note that the above is longhand for the following:

      providers: [ProductService]
  • The token can be a type, a string , or an OpaqueToken object (Pascal Precht – May, 2016).
  • OpaqueTokens are useful for avoiding naming collisions. …When you use a string you run the risk that a third party may be using the same string to define one of their providers. Remember that a provider token can be either a string or a type. OpaqueTokens basically allow us to create string-based tokens without the risk of running into any collisions.
  • As can be seen in the first snippet of DI code above,  an instance of the provider is passed into the component’s  constructor.
  • To inject a different implementation of a particular type, change to the longer notation in the @Component decorator’s provider’s array. For example, you can use the following for testing (Note that the component’s constructor does not have to change – only the providers property on the @Component decorator does):
    providers: [provide(ProductService, {useclass:MockProductService})];

See slide 13 of A2_unit3.pdf for an example of injecting a service }


Dependencies of dependencies

  • Common for an instance of a service class to be injected into a component and for the service class to have an instance of the Http class.
  • Http is implemented in the angular 2 Http module. So, you will need to import it your service.
  • Remember that an injector ALWAYS needs a provider – DI does NOT work if you don’t specify a provider. (In angular 2 (at least currently) you can’t specify a provider in a service, but you can specify them on components. This is an example of ‘leaky abstraction‘.)


HTTP_PROVIDERS is a special module that defines providers that can be used for Http. Define it in the component that the Http-dependent service is injected into (in our case, ProductService) or, one of its ancestors. The second place where you can declare dependencies is in the call to bootstrap function (the optional second parameter of the bootstrap method is an array of providers:

import {HTTP_PROVIDERS} from 'angular2/http';


class AppComponent {}
bootstrap(AppComponent, [HTTP_PROVIDERS]};

The hierarchy of Injectors

When an instance of an injectible object is not found in the current component, Angular 2 looks in the ancestor components

  • Platform injectors
    • App injectors
      • Parent component injectors
        • Child component injectors
          • Element injectors


Four flavors of provide() – You tell Angular how to create an object to be injected by invoking provider(), which can:

  • map a token to a useClass property
  • map a token to a useFactory property
    • Unlike the ‘useClass’ approach, this approach will specify a fat arrow function that will define what to inject.
  • map a token to a useValue property
  • map a token to a useExisting property (an alias)


Got through slide 29 (1:29 of mp4)

NOTE: In TypeScript a class can be used as an interface – class A can implement class B!