What is the difference between @Inject vs constructor injection as normal parameter in Angular 2?
You really should only use @Inject
for situations where the injectable token is not a class. If you are unfamiliar with what a token is, it is basically what Angular uses to recognize what to inject. For example
providers: [
AuthService,
{ provide: Http, useValue: new CustomHttpImpl() }
]
Here we have two different providers, the AuthService
and the CustomHttpImpl
. With the AuthService
the token is AuthService
. This means that we inject AuthService
, using obviously the AuthService
type
constructor(private authService: AuthService) {}
With this constructor, Angular knows to look for the AuthService
with the token AuthService
.
In the second provider, we provide a CustomHttpImpl
but this time we use the token Http
. So we cannot inject CustomHttpImpl
we need to inject Http
, since that is the token
// this will actually be the CustomHttpImpl, not Angular's Http
constructor(private http: Http)
// error: No provider for CustomHttpImpl
constructor(private http: CustomHttpImpl)
So you can tell from this that the tokens are all classes, which is enough for Angular to figure out to how to inject.
But let's say we have a String, or an Array of something we want to inject. We can't tie that to any class token, so we need to create an artificial token
import { OpaqueToken } from '@angular/core';
let numbers = [ 1, 2, 3, 4 ];
let config = '{ "some": "json", "config": "data" }'
const NUMBERS = new OpaqueToken('app.numbers');
const CONFIG = new OpaqueToken('app.config');
Now we have tokens for the items we want to inject. When we configure the providers
, we use those tokens, and when we inject, we @Inject(TOKEN)
providers: [
{ provide: NUMBERS, useValue: numbers },
{ provide: CONFIG, useValue: config }
]
constructor(@Inject(NUMBERS) numbers: number[], @Inject(CONFIG) config: string)
UPDATE
Now, with Angular 4, we should use InjectionToken
rather than OpaqueToken