dino-core
Version:
A dependency injection framework for NodeJS applications
150 lines • 5.51 kB
JavaScript
// 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.Injectable = void 0;
const Logger_1 = require("../Logger");
const MissingDependencyException_1 = require("../exceptions/MissingDependencyException");
const method_missing_exception_1 = require("../exceptions/method.missing.exception");
const Inject_1 = require("./decorators/Inject");
const scope_1 = require("./scope");
const stereotype_proxy_handler_factory_1 = require("./stereotype.proxy.handler.factory");
/**
* An abstract class to represent injectable resources.
*
* When contextScan is set to true, classes extending this class will be
* automatically discovered and injected on the application context.
*
* @public
* @abstract
*/
class Injectable {
constructor() {
const dependencies = (0, Inject_1.getInjectableDependencies)(this);
for (let index = 0; index < dependencies.length; index++) {
const dependency = dependencies[index];
const resolvedDependency = arguments[0] !== undefined ? arguments[0][dependency] : undefined;
if (resolvedDependency !== undefined) {
Object.defineProperty(this, dependency, {
value: resolvedDependency,
writable: false,
enumerable: true,
configurable: true
});
}
else {
throw MissingDependencyException_1.MissingDependencyException.create(dependency, this.constructor.name);
}
}
return new Proxy(this, this.getStereotypeProxyHandler().getProxyFor(this.getTypeName()));
}
/**
* Define the scope for this component, by default each component will be define with
* singleton scope, implementation may decide to override this method and define
* a different scope
*
* @returns {Scope} the {@link Scope} that this component lifecycle is bound.
*
* @default Scope.SINGLETON
* @public
*/
scope() {
return scope_1.Scope.SINGLETON;
}
/**
* Define the profile name this component should be activated for, return null for all
*
* @returns {String} a string representing the name this component should be activated for.
*
* @default null
* @public
*/
profile() {
return null;
}
/**
* Define if this component should be lazily loaded, false by default
*
* @returns {Boolean} a boolean flag defining i this component should be loaded lazily, true, or not false
*
* @default false
* @public
*/
lazy() {
return false;
}
/**
* Defines a list of dependencies that this component should wait before start its initialisation.
*
* @returns {Array<String>} and array of strings containing the names of the components to wait for,
* if left empty the component will be initialised on loading order.
*
* @default []
* @public
*/
dependsOn() {
return [];
}
/**
* Indicates that the results of the invocation of methods on this class can be cached.
*
* The method returns a CacheContext which describes which method and how is subject to caching.
* @returns {CacheContext} the context that describes the cache to create
*
* @default null
* @public
*/
cacheable() {
return null;
}
/**
* A utility method that allows to control if the injectable should be registered
* as part of the application context during context scan.
*
* This method is useful when loading of injectable is contingent on conditions or when
* the injectable needs to be excluded from loading, i.e. if represent an abstract class.
*
* By default this method will return true which means that all Injectables are eligible
* for auto-loading.
*
* @returns a flag indicating if this Injectable should be auto-loaded, default to true
*/
autoLoad() {
return true;
}
__call(method, _args) {
Logger_1.Logger.error(`Method [${method}] has been invoked but is not defined on [${this.constructor.name}]`);
throw method_missing_exception_1.MethodMissingException.create(method);
}
/**
* define the type name, i.e. Injectable, used this as a hook to load the proper handling proxy
* @returns string
* @private
*/
getTypeName() {
return 'Injectable';
}
/**
* Extension method allows to provide a custom proxy handler factory
*
* @returns StereotypeProxyHandlerFactory
*
* @private
*/
getStereotypeProxyHandler() {
return stereotype_proxy_handler_factory_1.StereotypeProxyHandlerFactory.getInstance();
}
}
exports.Injectable = Injectable;
//# sourceMappingURL=injectable.js.map
;