@inversifyjs/container
Version:
InversifyJs container
163 lines • 6.65 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceResolutionManager = void 0;
const common_1 = require("@inversifyjs/common");
const core_1 = require("@inversifyjs/core");
const InversifyContainerError_1 = require("../../error/models/InversifyContainerError");
const InversifyContainerErrorKind_1 = require("../../error/models/InversifyContainerErrorKind");
class ServiceResolutionManager {
#autobind;
#defaultScope;
#getActivationsResolutionParam;
#resolutionContext;
#onPlanHandlers;
#planParamsOperationsManager;
#serviceReferenceManager;
constructor(planParamsOperationsManager, serviceReferenceManager, autobind, defaultScope) {
this.#planParamsOperationsManager = planParamsOperationsManager;
this.#serviceReferenceManager = serviceReferenceManager;
this.#resolutionContext = this.#buildResolutionContext();
this.#autobind = autobind;
this.#defaultScope = defaultScope;
this.#getActivationsResolutionParam = (serviceIdentifier) => this.#serviceReferenceManager.activationService.get(serviceIdentifier);
this.#onPlanHandlers = [];
this.#serviceReferenceManager.onReset(() => {
this.#resetComputedProperties();
});
}
get(serviceIdentifier, options) {
const planResult = this.#buildPlanResult(false, serviceIdentifier, options);
const resolvedValue = this.#getFromPlanResult(planResult);
if ((0, common_1.isPromise)(resolvedValue)) {
throw new InversifyContainerError_1.InversifyContainerError(InversifyContainerErrorKind_1.InversifyContainerErrorKind.invalidOperation, `Unexpected asynchronous service when resolving service "${(0, common_1.stringifyServiceIdentifier)(serviceIdentifier)}"`);
}
return resolvedValue;
}
getAll(serviceIdentifier, options) {
const planResult = this.#buildPlanResult(true, serviceIdentifier, options);
const resolvedValue = this.#getFromPlanResult(planResult);
if ((0, common_1.isPromise)(resolvedValue)) {
throw new InversifyContainerError_1.InversifyContainerError(InversifyContainerErrorKind_1.InversifyContainerErrorKind.invalidOperation, `Unexpected asynchronous service when resolving service "${(0, common_1.stringifyServiceIdentifier)(serviceIdentifier)}"`);
}
return resolvedValue;
}
async getAllAsync(serviceIdentifier, options) {
const planResult = this.#buildPlanResult(true, serviceIdentifier, options);
return this.#getFromPlanResult(planResult);
}
async getAsync(serviceIdentifier, options) {
const planResult = this.#buildPlanResult(false, serviceIdentifier, options);
return this.#getFromPlanResult(planResult);
}
onPlan(handler) {
this.#onPlanHandlers.push(handler);
}
#resetComputedProperties() {
this.#resolutionContext = this.#buildResolutionContext();
}
#buildGetPlanOptions(isMultiple, serviceIdentifier, options) {
const name = options?.name;
const optional = options?.optional ?? false;
const tag = options?.tag;
if (isMultiple) {
return {
chained: options?.chained ?? false,
isMultiple,
name,
optional,
serviceIdentifier,
tag,
};
}
else {
return {
isMultiple,
name,
optional,
serviceIdentifier,
tag,
};
}
}
#buildPlanParams(serviceIdentifier, isMultiple, options) {
const planParams = {
autobindOptions: (options?.autobind ?? this.#autobind)
? {
scope: this.#defaultScope,
}
: undefined,
operations: this.#planParamsOperationsManager.planParamsOperations,
rootConstraints: this.#buildPlanParamsConstraints(serviceIdentifier, isMultiple, options),
servicesBranch: [],
};
this.#handlePlanParamsRootConstraints(planParams, options);
return planParams;
}
#buildPlanParamsConstraints(serviceIdentifier, isMultiple, options) {
if (isMultiple) {
return {
chained: options?.chained ?? false,
isMultiple,
serviceIdentifier,
};
}
else {
return {
isMultiple,
serviceIdentifier,
};
}
}
#buildPlanResult(isMultiple, serviceIdentifier, options) {
const getPlanOptions = this.#buildGetPlanOptions(isMultiple, serviceIdentifier, options);
const planResultFromCache = this.#serviceReferenceManager.planResultCacheService.get(getPlanOptions);
if (planResultFromCache !== undefined) {
return planResultFromCache;
}
const planResult = (0, core_1.plan)(this.#buildPlanParams(serviceIdentifier, isMultiple, options));
for (const handler of this.#onPlanHandlers) {
handler(getPlanOptions, planResult);
}
return planResult;
}
#buildResolutionContext() {
return {
get: this.get.bind(this),
getAll: this.getAll.bind(this),
getAllAsync: this.getAllAsync.bind(this),
getAsync: this.getAsync.bind(this),
};
}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
#getFromPlanResult(planResult) {
return (0, core_1.resolve)({
context: this.#resolutionContext,
getActivations: this.#getActivationsResolutionParam,
planResult,
requestScopeCache: new Map(),
});
}
#handlePlanParamsRootConstraints(planParams, options) {
if (options === undefined) {
return;
}
if (options.name !== undefined) {
planParams.rootConstraints.name = options.name;
}
if (options.optional === true) {
planParams.rootConstraints.isOptional = true;
}
if (options.tag !== undefined) {
planParams.rootConstraints.tag = {
key: options.tag.key,
value: options.tag.value,
};
}
if (planParams.rootConstraints.isMultiple) {
planParams.rootConstraints.chained =
options?.chained ?? false;
}
}
}
exports.ServiceResolutionManager = ServiceResolutionManager;
//# sourceMappingURL=ServiceResolutionManager.js.map