Skip to content

Instantly share code, notes, and snippets.

@kamiazya
Last active February 26, 2020 08:35
Show Gist options
  • Save kamiazya/bf69a3b86242b54dfb8ccfdb9659f0c7 to your computer and use it in GitHub Desktop.
Save kamiazya/bf69a3b86242b54dfb8ccfdb9659f0c7 to your computer and use it in GitHub Desktop.
import { Injectable, InjectionToken, Injector } from 'injection-js';
type LifeCycleFunction = () => Promise<void>;
export const INITIALIZER = new InjectionToken<LifeCycleFunction>('application.life-cycle.initializer');
export const TERMINATOR = new InjectionToken<LifeCycleFunction>('application.life-cycle.TERMINATOR');
@Injectable()
export class Application {
constructor(private injector: Injector) {}
/**
* Initialize application.
*/
public async initialize(): Promise<void> {
return this.execute(INITIALIZER);
}
/**
* Terminate application.
*/
public async terminate(): Promise<void> {
return this.execute(TERMINATOR);
}
/**
* Execute the specified life cycle process.
*/
private async execute(token: InjectionToken<LifeCycleFunction>): Promise<void> {
const functions = this.injector.get<LifeCycleFunction[]>(token, []);
await Promise.all(functions.map(f => f()));
}
}
import 'reflect-metadata';
import { Provider, Type } from 'injection-js';
/**
* Interface defining a Dynamic Module.
*/
export interface IDynamicModule extends IModuleMetadata {
/**
* A module
*/
module: Type<any>;
}
/**
* Interface defining the property object that describes the module.
*/
export interface IModuleMetadata {
/**
* Optional list of imported modules that export the providers which are
* required in this module.
*/
imports?: IDynamicModule[];
/**
* Optional list of providers that will be instantiated by the Nest injector
* and that may be shared at least across this module.
*/
providers?: Provider[];
/**
* Optional list of the subset of providers that are provided by this module
* and should be available in other modules which import this module.
*/
exports?: Array<IDynamicModule | Provider>;
}
const ModuleMetadataKeys: Array<keyof IModuleMetadata> = ['imports', 'providers', 'exports'];
/**
* Decorator that marks a class as a module.
*
* @param metadata module configuration metadata
*/
export function Module(metadata: IModuleMetadata): ClassDecorator {
return (target: object) => {
Object.entries(metadata)
.filter(([property, data]) => property in ModuleMetadataKeys && !!data)
.forEach(([property, data]) => Reflect.defineMetadata(property, data, target));
};
}
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"moduleResolution": "node",
"baseUrl": "./",
"esModuleInterop": true,
"outDir": "./dist",
"sourceMap": true,
"declaration": true,
"declarationMap": true,
"importHelpers": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"lib": [
"es2016",
"esnext",
"es2015.reflect"
]
},
"include": [
"./src/**/*.ts"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment