2018-02-16 08:45:21 -08:00
|
|
|
/**
|
|
|
|
|
* @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 {ClassProvider, ClassSansProvider, ConstructorProvider, ConstructorSansProvider, ExistingProvider, ExistingSansProvider, FactoryProvider, FactorySansProvider, StaticClassProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from './provider';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Information about how a type or `InjectionToken` interfaces with the DI system.
|
|
|
|
|
*
|
|
|
|
|
* At a minimum, this includes a `factory` which defines how to create the given type `T`, possibly
|
|
|
|
|
* requesting injection of other types if necessary.
|
|
|
|
|
*
|
|
|
|
|
* Optionally, a `providedIn` parameter specifies that the given type belongs to a particular
|
2018-04-13 13:34:39 -07:00
|
|
|
* `ɵInjectorDef`, `NgModule`, or a special scope (e.g. `'root'`). A value of `null` indicates
|
2018-02-16 08:45:21 -08:00
|
|
|
* that the injectable does not belong to any scope.
|
|
|
|
|
*
|
2018-04-13 13:34:39 -07:00
|
|
|
* NOTE: This is a semi public API, and there are no guaranties that the shape of this API will
|
|
|
|
|
* remain consistent between version. Use with caution.
|
2018-02-16 08:45:21 -08:00
|
|
|
*
|
|
|
|
|
* @experimental
|
|
|
|
|
*/
|
2018-04-13 13:34:39 -07:00
|
|
|
export interface ɵInjectableDef<T> {
|
2018-04-12 15:54:16 -07:00
|
|
|
/**
|
|
|
|
|
* Specifies that the given type belongs to a particular injector:
|
|
|
|
|
* - `InjectorType` such as `NgModule`,
|
|
|
|
|
* - `'root'` the root injector
|
|
|
|
|
* - `'any'` all injectors.
|
|
|
|
|
* - `null`, does not belong to any injector. Must be explicitly listed in the injector
|
|
|
|
|
* `providers`.
|
|
|
|
|
*/
|
2018-02-16 08:45:21 -08:00
|
|
|
providedIn: InjectorType<any>|'root'|'any'|null;
|
2018-04-12 15:54:16 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Factory method to execute to create an instance of the injectable.
|
|
|
|
|
*/
|
2018-02-16 08:45:21 -08:00
|
|
|
factory: () => T;
|
2018-04-12 15:54:16 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* In a case of no explicit injector, a location where the instance of the injectable is stored.
|
|
|
|
|
*/
|
|
|
|
|
value: T|undefined;
|
2018-02-16 08:45:21 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Information about the providers to be included in an `Injector` as well as how the given type
|
|
|
|
|
* which carries the information should be created by the DI system.
|
|
|
|
|
*
|
2018-04-13 13:34:39 -07:00
|
|
|
* An `ɵInjectorDef` can import other types which have `InjectorDefs`, forming a deep nested
|
2018-02-16 08:45:21 -08:00
|
|
|
* structure of providers with a defined priority (identically to how `NgModule`s also have
|
|
|
|
|
* an import/dependency structure).
|
|
|
|
|
*
|
|
|
|
|
* @experimental
|
|
|
|
|
*/
|
2018-04-13 13:34:39 -07:00
|
|
|
export interface ɵInjectorDef<T> {
|
2018-02-16 08:45:21 -08:00
|
|
|
factory: () => T;
|
|
|
|
|
|
|
|
|
|
// TODO(alxhub): Narrow down the type here once decorators properly change the return type of the
|
|
|
|
|
// class they are decorating (to add the ngInjectableDef property for example).
|
|
|
|
|
providers: (Type<any>|ValueProvider|ExistingProvider|FactoryProvider|ConstructorProvider|
|
|
|
|
|
StaticClassProvider|ClassProvider|any[])[];
|
|
|
|
|
|
|
|
|
|
imports: (InjectorType<any>|InjectorTypeWithProviders<any>)[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2018-04-13 13:34:39 -07:00
|
|
|
* A `Type` which has an `ɵInjectableDef` static field.
|
2018-02-16 08:45:21 -08:00
|
|
|
*
|
|
|
|
|
* `InjectableDefType`s contain their own Dependency Injection metadata and are usable in an
|
2018-04-13 13:34:39 -07:00
|
|
|
* `ɵInjectorDef`-based `StaticInjector.
|
2018-02-16 08:45:21 -08:00
|
|
|
*
|
|
|
|
|
* @experimental
|
|
|
|
|
*/
|
2018-04-13 13:34:39 -07:00
|
|
|
export interface InjectableType<T> extends Type<T> { ngInjectableDef: ɵInjectableDef<T>; }
|
2018-02-16 08:45:21 -08:00
|
|
|
|
|
|
|
|
/**
|
2018-04-13 13:34:39 -07:00
|
|
|
* A type which has an `ɵInjectorDef` static field.
|
2018-02-16 08:45:21 -08:00
|
|
|
*
|
|
|
|
|
* `InjectorDefTypes` can be used to configure a `StaticInjector`.
|
|
|
|
|
*
|
|
|
|
|
* @experimental
|
|
|
|
|
*/
|
2018-04-13 13:34:39 -07:00
|
|
|
export interface InjectorType<T> extends Type<T> { ngInjectorDef: ɵInjectorDef<T>; }
|
2018-02-16 08:45:21 -08:00
|
|
|
|
|
|
|
|
/**
|
2018-04-13 13:34:39 -07:00
|
|
|
* Describes the `ɵInjectorDef` equivalent of a `ModuleWithProviders`, an `InjectorDefType` with an
|
2018-02-16 08:45:21 -08:00
|
|
|
* associated array of providers.
|
|
|
|
|
*
|
2018-04-13 13:34:39 -07:00
|
|
|
* Objects of this type can be listed in the imports section of an `ɵInjectorDef`.
|
2018-02-16 08:45:21 -08:00
|
|
|
*
|
|
|
|
|
* @experimental
|
|
|
|
|
*/
|
|
|
|
|
export interface InjectorTypeWithProviders<T> {
|
|
|
|
|
ngModule: InjectorType<T>;
|
|
|
|
|
providers?: (Type<any>|ValueProvider|ExistingProvider|FactoryProvider|ConstructorProvider|
|
|
|
|
|
StaticClassProvider|ClassProvider|any[])[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2018-04-13 13:34:39 -07:00
|
|
|
* Construct an `ɵInjectableDef` which defines how a token will be constructed by the DI system, and
|
2018-02-16 08:45:21 -08:00
|
|
|
* in which injectors (if any) it will be available.
|
|
|
|
|
*
|
|
|
|
|
* This should be assigned to a static `ngInjectableDef` field on a type, which will then be an
|
|
|
|
|
* `InjectableType`.
|
|
|
|
|
*
|
|
|
|
|
* Options:
|
|
|
|
|
* * `providedIn` determines which injectors will include the injectable, by either associating it
|
|
|
|
|
* with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
|
|
|
|
|
* provided in the `'root'` injector, which will be the application-level injector in most apps.
|
|
|
|
|
* * `factory` gives the zero argument function which will create an instance of the injectable.
|
|
|
|
|
* The factory can call `inject` to access the `Injector` and request injection of dependencies.
|
|
|
|
|
*
|
|
|
|
|
* @experimental
|
|
|
|
|
*/
|
|
|
|
|
export function defineInjectable<T>(opts: {
|
2018-04-12 15:54:16 -07:00
|
|
|
providedIn?: Type<any>| 'root' | 'any' | null,
|
2018-02-16 08:45:21 -08:00
|
|
|
factory: () => T,
|
2018-04-13 13:34:39 -07:00
|
|
|
}): ɵInjectableDef<T> {
|
2018-02-16 08:45:21 -08:00
|
|
|
return {
|
2018-04-12 15:54:16 -07:00
|
|
|
providedIn: opts.providedIn as any || null,
|
2018-02-16 08:45:21 -08:00
|
|
|
factory: opts.factory,
|
2018-04-12 15:54:16 -07:00
|
|
|
value: undefined,
|
2018-02-16 08:45:21 -08:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2018-04-13 13:34:39 -07:00
|
|
|
* Construct an `ɵInjectorDef` which configures an injector.
|
2018-02-16 08:45:21 -08:00
|
|
|
*
|
|
|
|
|
* This should be assigned to a static `ngInjectorDef` field on a type, which will then be an
|
|
|
|
|
* `InjectorType`.
|
|
|
|
|
*
|
|
|
|
|
* Options:
|
|
|
|
|
*
|
|
|
|
|
* * `factory`: an `InjectorType` is an instantiable type, so a zero argument `factory` function to
|
|
|
|
|
* create the type must be provided. If that factory function needs to inject arguments, it can
|
|
|
|
|
* use the `inject` function.
|
|
|
|
|
* * `providers`: an optional array of providers to add to the injector. Each provider must
|
|
|
|
|
* either have a factory or point to a type which has an `ngInjectableDef` static property (the
|
|
|
|
|
* type must be an `InjectableType`).
|
|
|
|
|
* * `imports`: an optional array of imports of other `InjectorType`s or `InjectorTypeWithModule`s
|
|
|
|
|
* whose providers will also be added to the injector. Locally provided types will override
|
|
|
|
|
* providers from imports.
|
|
|
|
|
*
|
|
|
|
|
* @experimental
|
|
|
|
|
*/
|
|
|
|
|
export function defineInjector(options: {factory: () => any, providers?: any[], imports?: any[]}):
|
2018-04-13 13:34:39 -07:00
|
|
|
ɵInjectorDef<any> {
|
2018-02-16 08:45:21 -08:00
|
|
|
return {
|
|
|
|
|
factory: options.factory,
|
|
|
|
|
providers: options.providers || [],
|
|
|
|
|
imports: options.imports || [],
|
|
|
|
|
};
|
|
|
|
|
}
|