angular/packages/core/src/di/injection_token.ts
2018-10-19 14:35:53 -07:00

77 lines
2.5 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Type} from '../type';
import {defineInjectable} from './defs';
/**
* Creates a token that can be used in a DI Provider.
*
* Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
* runtime representation) such as when injecting an interface, callable type, array or
* parametrized type.
*
* `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
* the `Injector`. This provides additional level of type safety.
*
* ```
* interface MyInterface {...}
* var myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
* // myInterface is inferred to be MyInterface.
* ```
*
* When creating an `InjectionToken`, you can optionally specify a factory function which returns
* (possibly by creating) a default value of the parameterized type `T`. This sets up the
* `InjectionToken` using this factory as a provider as if it was defined explicitly in the
* application's root injector. If the factory function, which takes zero arguments, needs to inject
* dependencies, it can do so using the `inject` function. See below for an example.
*
* Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
* overrides the above behavior and marks the token as belonging to a particular `@NgModule`. As
* mentioned above, `'root'` is the default value for `providedIn`.
*
* @usageNotes
* ### Basic Example
*
* ### Plain InjectionToken
*
* {@example core/di/ts/injector_spec.ts region='InjectionToken'}
*
* ### Tree-shakable InjectionToken
*
* {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
*
*
* @publicApi
*/
export class InjectionToken<T> {
/** @internal */
readonly ngMetadataName = 'InjectionToken';
readonly ngInjectableDef: never|undefined;
constructor(protected _desc: string, options?: {
providedIn?: Type<any>| 'root' | null,
factory: () => T
}) {
if (options !== undefined) {
this.ngInjectableDef = defineInjectable({
providedIn: options.providedIn || 'root',
factory: options.factory,
});
} else {
this.ngInjectableDef = undefined;
}
}
toString(): string { return `InjectionToken ${this._desc}`; }
}
export interface InjectableDefToken<T> extends InjectionToken<T> { ngInjectableDef: never; }