injection-js
Version:
Dependency Injection library for JavaScript and TypeScript
224 lines • 7.99 kB
JavaScript
/**
* @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 { reflector } from './reflection/reflection';
import { Type } from './facade/type';
import { resolveForwardRef } from './forward_ref';
import { InjectionToken } from './injection_token';
import { Inject, Optional, Self, SkipSelf } from './metadata';
import { invalidProviderError, mixingMultiProvidersWithRegularProvidersError, noAnnotationError } from './reflective_errors';
import { ReflectiveKey } from './reflective_key';
/**
* `Dependency` is used by the framework to extend DI.
* This is internal to Angular and should not be used directly.
*/
var ReflectiveDependency = /** @class */ (function () {
function ReflectiveDependency(key, optional, visibility) {
this.key = key;
this.optional = optional;
this.visibility = visibility;
}
ReflectiveDependency.fromKey = function (key) {
return new ReflectiveDependency(key, false, null);
};
return ReflectiveDependency;
}());
export { ReflectiveDependency };
var _EMPTY_LIST = [];
// tslint:disable-next-line:class-name
var ResolvedReflectiveProvider_ = /** @class */ (function () {
function ResolvedReflectiveProvider_(key, resolvedFactories, multiProvider) {
this.key = key;
this.resolvedFactories = resolvedFactories;
this.multiProvider = multiProvider;
}
Object.defineProperty(ResolvedReflectiveProvider_.prototype, "resolvedFactory", {
get: function () {
return this.resolvedFactories[0];
},
enumerable: false,
configurable: true
});
return ResolvedReflectiveProvider_;
}());
export { ResolvedReflectiveProvider_ };
/**
* An internal resolved representation of a factory function created by resolving {@link
* Provider}.
* @experimental
*/
var ResolvedReflectiveFactory = /** @class */ (function () {
function ResolvedReflectiveFactory(
/**
* Factory function which can return an instance of an object represented by a key.
*/
factory,
/**
* Arguments (dependencies) to the `factory` function.
*/
dependencies) {
this.factory = factory;
this.dependencies = dependencies;
}
return ResolvedReflectiveFactory;
}());
export { ResolvedReflectiveFactory };
/**
* Resolve a single provider.
*/
function resolveReflectiveFactory(provider) {
var factoryFn;
var resolvedDeps;
if (provider.useClass) {
var useClass = resolveForwardRef(provider.useClass);
factoryFn = reflector.factory(useClass);
resolvedDeps = _dependenciesFor(useClass);
}
else if (provider.useExisting) {
factoryFn = function (aliasInstance) { return aliasInstance; };
resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
}
else if (provider.useFactory) {
factoryFn = provider.useFactory;
resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
}
else {
factoryFn = function () { return provider.useValue; };
resolvedDeps = _EMPTY_LIST;
}
return new ResolvedReflectiveFactory(factoryFn, resolvedDeps);
}
/**
* Converts the {@link Provider} into {@link ResolvedProvider}.
*
* {@link Injector} internally only uses {@link ResolvedProvider}, {@link Provider} contains
* convenience provider syntax.
*/
function resolveReflectiveProvider(provider) {
return new ResolvedReflectiveProvider_(ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi || false);
}
/**
* Resolve a list of Providers.
*/
export function resolveReflectiveProviders(providers) {
var normalized = _normalizeProviders(providers, []);
var resolved = normalized.map(resolveReflectiveProvider);
var resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map());
return Array.from(resolvedProviderMap.values());
}
/**
* Merges a list of ResolvedProviders into a list where
* each key is contained exactly once and multi providers
* have been merged.
*/
export function mergeResolvedReflectiveProviders(providers, normalizedProvidersMap) {
for (var i = 0; i < providers.length; i++) {
var provider = providers[i];
var existing = normalizedProvidersMap.get(provider.key.id);
if (existing) {
if (provider.multiProvider !== existing.multiProvider) {
throw mixingMultiProvidersWithRegularProvidersError(existing, provider);
}
if (provider.multiProvider) {
for (var j = 0; j < provider.resolvedFactories.length; j++) {
existing.resolvedFactories.push(provider.resolvedFactories[j]);
}
}
else {
normalizedProvidersMap.set(provider.key.id, provider);
}
}
else {
var resolvedProvider = void 0;
if (provider.multiProvider) {
resolvedProvider = new ResolvedReflectiveProvider_(provider.key, provider.resolvedFactories.slice(), provider.multiProvider);
}
else {
resolvedProvider = provider;
}
normalizedProvidersMap.set(provider.key.id, resolvedProvider);
}
}
return normalizedProvidersMap;
}
function _normalizeProviders(providers, res) {
providers.forEach(function (b) {
if (b instanceof Type) {
res.push({ provide: b, useClass: b });
}
else if (b && typeof b === 'object' && b.provide !== undefined) {
res.push(b);
}
else if (b instanceof Array) {
_normalizeProviders(b, res);
}
else {
throw invalidProviderError(b);
}
});
return res;
}
export function constructDependencies(typeOrFunc, dependencies) {
if (!dependencies) {
return _dependenciesFor(typeOrFunc);
}
else {
var params_1 = dependencies.map(function (t) { return [t]; });
return dependencies.map(function (t) { return _extractToken(typeOrFunc, t, params_1); });
}
}
function _dependenciesFor(typeOrFunc) {
var params = reflector.parameters(typeOrFunc);
if (!params)
return [];
if (params.some(function (p) { return p == null; })) {
throw noAnnotationError(typeOrFunc, params);
}
return params.map(function (p) { return _extractToken(typeOrFunc, p, params); });
}
function _extractToken(typeOrFunc, metadata, params) {
var token = null;
var optional = false;
if (!Array.isArray(metadata)) {
if (metadata instanceof Inject) {
return _createDependency(metadata['token'], optional, null);
}
else {
return _createDependency(metadata, optional, null);
}
}
var visibility = null;
for (var i = 0; i < metadata.length; ++i) {
var paramMetadata = metadata[i];
if (paramMetadata instanceof Type) {
token = paramMetadata;
}
else if (paramMetadata instanceof Inject) {
token = paramMetadata['token'];
}
else if (paramMetadata instanceof Optional) {
optional = true;
}
else if (paramMetadata instanceof Self || paramMetadata instanceof SkipSelf) {
visibility = paramMetadata;
}
else if (paramMetadata instanceof InjectionToken) {
token = paramMetadata;
}
}
token = resolveForwardRef(token);
if (token != null) {
return _createDependency(token, optional, visibility);
}
else {
throw noAnnotationError(typeOrFunc, params);
}
}
function _createDependency(token, optional, visibility) {
return new ReflectiveDependency(ReflectiveKey.get(token), optional, visibility);
}
//# sourceMappingURL=reflective_provider.js.map