import {Application} from './Application'; import {Container, DependencyKey} from "../di"; /** * Base type for a class that supports binding methods by string. */ export interface Bindable { getBoundMethod(methodName: string): (...args: any[]) => any } /** * Returns true if the given object is bindable. * @param what * @return boolean */ export function isBindable(what: any): what is Bindable { return ( what && typeof what.getBoundMethod === 'function' && what.getBoundMethod.length === 1 && typeof what.getBoundMethod('getBoundMethod') === 'function' ) } /** * Base for classes that gives access to the global application and container. */ export class AppClass { /** The global application instance. */ private readonly appClassApplication!: Application; constructor() { this.appClassApplication = Application.getApplication(); } /** Get the global Application. */ protected app(): Application { return this.appClassApplication; } /** Get the global Container. */ protected container(): Container { return this.appClassApplication; } /** Call the `make()` method on the global container. */ protected make(target: DependencyKey, ...parameters: any[]): T { return this.container().make(target, ...parameters) } /** * Get the method with the given name from this class, bound to this class. * @param {string} methodName * @return function */ public getBoundMethod(methodName: string): (...args: any[]) => any { // @ts-ignore if ( typeof this[methodName] !== 'function' ) { throw new TypeError(`Attempt to get bound method for non-function type: ${methodName}`) } return (...args: any[]): any => { // @ts-ignore return this[methodName](...args) } } }