UNPKG

dino-core

Version:

A dependency injection framework for NodeJS applications

86 lines 3.71 kB
"use strict"; // Copyright 2018 Quirino Brizi [quirino.brizi@gmail.com] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. Object.defineProperty(exports, "__esModule", { value: true }); exports.ApplicationContextBuilder = void 0; const Logger_1 = require("../Logger"); const ApplicationContextHelper_1 = require("./ApplicationContextHelper"); /** * Build the application context starting from the provided configuration * * @public * @since 0.0.1 */ class ApplicationContextBuilder { /** * @constructor */ constructor() { this.applicationContextHelper = new ApplicationContextHelper_1.ApplicationContextHelper(); } /** * Build the application context. * @param {Array<ComponentDescriptor>} componentDescriptors the component descriptors holding the loading information for components * @param {ApplicationContext} context the application context where components will be registered * * @returns {Promise<ApplicationContext>} a promise resolved with the updated application context * @public */ async build(componentDescriptors, context) { let failed = []; const environment = context.resolve('environment'); const dependencyTree = this.applicationContextHelper.buildDependencyTree(componentDescriptors, environment.getOrDefault('dino:dependencyTree:enabled', true)); for (const [level, components] of dependencyTree) { for (let index = 0; index < components.length; index++) { const componentDescriptor = components[index]; Logger_1.Logger.debug(`computing ${componentDescriptor.getName()} at level ${Symbol.keyFor(level.valueOf())}`); this.tryRegisterOrRecordFailure(context, componentDescriptor, failed); } } let retry = 0; while (failed.length > 0 && retry < 5) { const newFailures = []; for (let index = 0; index < failed.length; index++) { const component = failed[index]; this.tryRegisterOrRecordFailure(context, component, newFailures); } failed = newFailures; retry++; } if (failed.length > 0) { throw Error(`unable to resolve all dependencies ${failed.map((cd) => cd.getName()).join(',')}`); } return context; } /** * Try register a component on this context * * @param {ApplicationContext} context the application context * @param {ComponentDescriptor} componentDescriptor the component descriptor * @param {Array<ComponentDescriptor>} accumulator the accumulator for failed registrations * * @private */ tryRegisterOrRecordFailure(context, componentDescriptor, accumulator) { try { context.add(componentDescriptor); } catch (error) { Logger_1.Logger.debug(`>>> unable to register component ${componentDescriptor.getName()}: ${error}`); accumulator.push(componentDescriptor); } } } exports.ApplicationContextBuilder = ApplicationContextBuilder; //# sourceMappingURL=ApplicationContextBuilder.js.map