UNPKG

@inversifyjs/container

Version:

InversifyJs container

145 lines 6.43 kB
"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; #getBindingsPlanParams; #resolutionContext; #onPlanHandlers; #serviceReferenceManager; #setBindingParamsPlan; constructor(serviceReferenceManager, autobind, defaultScope) { this.#serviceReferenceManager = serviceReferenceManager; this.#resolutionContext = this.#buildResolutionContext(); this.#autobind = autobind; this.#defaultScope = defaultScope; this.#getActivationsResolutionParam = (serviceIdentifier) => this.#serviceReferenceManager.activationService.get(serviceIdentifier); this.#getBindingsPlanParams = this.#serviceReferenceManager.bindingService.get.bind(this.#serviceReferenceManager.bindingService); this.#onPlanHandlers = []; this.#setBindingParamsPlan = this.#setBinding.bind(this); 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.#getBindingsPlanParams = this.#serviceReferenceManager.bindingService.get.bind(this.#serviceReferenceManager.bindingService); this.#setBindingParamsPlan = this.#setBinding.bind(this); this.#resolutionContext = this.#buildResolutionContext(); } #buildGetPlanOptions(isMultiple, serviceIdentifier, options) { return { isMultiple, name: options?.name, optional: options?.optional, serviceIdentifier, tag: options?.tag, }; } #buildPlanParams(serviceIdentifier, isMultiple, options) { const planParams = { autobindOptions: (options?.autobind ?? this.#autobind) ? { scope: this.#defaultScope, } : undefined, getBindings: this.#getBindingsPlanParams, getClassMetadata: core_1.getClassMetadata, rootConstraints: { isMultiple, serviceIdentifier, }, servicesBranch: [], setBinding: this.#setBindingParamsPlan, }; this.#handlePlanParamsRootConstraints(planParams, options); return planParams; } #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)); this.#serviceReferenceManager.planResultCacheService.set(getPlanOptions, planResult); 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, }; } } #setBinding(binding) { this.#serviceReferenceManager.bindingService.set(binding); this.#serviceReferenceManager.planResultCacheService.clearCache(); } } exports.ServiceResolutionManager = ServiceResolutionManager; //# sourceMappingURL=ServiceResolutionManager.js.map