@Inject and @Injectable

Statements that look like @SomeName are decorators. Decorators are a proposed extension to JavaScript. In short, decorators let programmers modify and/or tag methods, classes, properties and parameters. There is a lot to decorators. In this section the focus will be on decorators relevant to DI: @Inject and @Injectable. For more information on Decorators please see the EcmaScript 6 and TypeScript Features section.

@Inject()

@Inject() is a manual mechanism for letting Angular 2 know that a parameter must be injected. It can be used like so:

import { Component, Inject } from '@angular/core';
import { Hamburger } from '../services/hamburger';

@Component({
  selector: 'app',
  template: `Bun Type: {{ bunType }}`
})
export class App {
  bunType: string;
  constructor(@Inject(Hamburger) h) {
    this.bunType = h.bun.type;
  }
}

In the above we've asked for h to be the singleton Angular associates with the class symbol Hamburger by calling @Inject(Hamburger). It's important to note that we're using Hamburger for its typings and as a reference to its singleton. We are not using Hamburger to instantiate anything, Angular does that for us behind the scenes.

When using TypeScript, @Inject is only needed for injecting primitives. TypeScript's types let Angular 2 know what to do in most cases. The above example would be simplified in TypeScript to:

import { Component } from '@angular/core';
import { Hamburger } from '../services/hamburger';

@Component({
  selector: 'app',
  template: `Bun Type: {{ bunType }}`
})
export class App {
  bunType: string;
  constructor(h: Hamburger) {
    this.bunType = h.bun.type;
  }
}

View Example

@Injectable()

@Injectable() lets Angular 2 know that a class can be used with the dependency injector. @Injectable() is not strictly required if the class has other Angular 2 decorators on it or does not have any dependencies.
What is important is that any class that is going to be injected with Angular 2 is decorated. However, best practice is to decorate injectables with @Injectable(), as it makes more sense to the reader.

Here's an example of Hamburger marked up with @Injectable:

import { Injectable } from '@angular/core';
import { Bun } from './bun';
import { Patty } from './patty';
import { Toppings } from './toppings';

@Injectable()
export class Hamburger {
  constructor(public bun: Bun, public patty: Patty, public toppings: Toppings) {
  }
}

In the above example Angular 2's injector determines what to inject into Hamburger's constructor by using type information. This is possible because these particular dependencies are typed, and are not primitive types. In some cases Angular 2's DI needs more information than just types.

results matching ""

    No results matching ""