@rokkit.ts/dependency-injection
Version:
TypeScript dependency injection library using decorators for the rokkit.ts framework and other projects
103 lines • 4.43 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const __1 = require("..");
/**
* @class RokkitDI
* This class exposes the API to register Injectables on the dependencies container.
* The container is maintained as a singleton, so that all module of your application use the same container nad get the same injectors.
* In order to retrieve an instance you can decide if you want to get an singleton or a new instance.
*/
class DependencyInjectionContainer {
constructor() {
this.injectables = new Map();
this.instances = new Map();
}
registerInjectable(classConstructor, classConstructorArguments) {
// check scanned arguments when the params are empty
const injectorArgs = this.updateProvidedWithScannedArguments(classConstructor.name, classConstructorArguments);
// create injector
const injector = new __1.Injector(classConstructor, injectorArgs);
// register injector on static map!
this.injectables.set(classConstructor.name, injector);
return this;
}
/**
* @function singletonOf
* This function let's you retrieve a registered intjector as a singleton object. That means
* that each next call will get the exact same instances.
* @param injectable:string Name of the class you want to retrieve
* @returns any object that is already stored or we be create by the corresponding injector
*/
singletonOf(injectable) {
var _a;
return ((_a = this.instances.get(injectable)) !== null && _a !== void 0 ? _a : this.instantiateSingleton(injectable));
}
/**
* @function instanceOf
* This function let's you create new instance of the registered injector.
* That means that every time you call this function you will retrieve a new object.
* @param injectable:string Name of the class you want to retrieve
* @returns any new object that is created by the corresponding injector
*/
instanceOf(injectable) {
try {
const injector = this.injectorFor(injectable);
// create values that are not present by now!
injector.ClassConstructorArguments = this.instanctiateArgValues(injector, 'SINGLETON');
return injector.createInstance();
}
catch (error) {
throw new Error(`Could not instantiate an instance of ${injectable}: : ${error.message}`);
}
}
updateProvidedWithScannedArguments(injectorName, providedArgs = []) {
const scannedArgs = __1.TypeScannerSingleton.injectorArgumentsFor(injectorName);
return scannedArgs.map((arg, index) => {
const providedArg = providedArgs.find(pargs => pargs.index === index);
return {
index,
type: arg.type,
value: providedArg === null || providedArg === void 0 ? void 0 : providedArg.value
};
});
}
instantiateSingleton(injectable) {
try {
this.instances.set(injectable, this.instanceOf(injectable));
return this.instances.get(injectable);
}
catch (error) {
throw new Error(`Could not instantiate a singlton of ${injectable}: ${error.message}`);
}
}
injectorFor(injectable) {
const injector = this.injectables.get(injectable);
if (!injector) {
throw new Error(`Could not find a registered injector for the name: ${injectable}.`);
}
return injector;
}
instanctiateArgValues(injector, mode) {
return injector.ClassConstructorArguments.map(arg => {
var _a;
if (this.isUserObject(arg)) {
arg.value =
((_a = arg.value) !== null && _a !== void 0 ? _a : mode === 'SINGLETON') ? this.singletonOf(arg.type)
: this.injectorFor(arg.type);
}
return arg;
});
}
isUserObject(argument) {
return !(argument.type === 'string' ||
argument.type === 'bigint' ||
argument.type === 'object' ||
argument.type === 'number' ||
argument.type === 'undefined' ||
argument.type === 'boolean' ||
argument.type === 'symbol' ||
argument.type === 'function');
}
}
exports.RokkitDI = new DependencyInjectionContainer();
//# sourceMappingURL=RokkitDI.js.map
;