Skip to content

Instantly share code, notes, and snippets.

@siandreev
Created October 20, 2021 11:35
Show Gist options
  • Save siandreev/6ab4872d513af0e234e8b14dbf4f488b to your computer and use it in GitHub Desktop.
Save siandreev/6ab4872d513af0e234e8b14dbf4f488b to your computer and use it in GitHub Desktop.
InjectDecorator
import 'reflect-metadata';
class Injector {
// Map<interfaceType, instance>
services: Map<Function, Object> = new Map();
registerService(interfaceType: Function, instance: Object) {
this.services.set(interfaceType, instance);
}
getService(interfaceType: Function): Object {
return this.services.get(interfaceType);
}
}
class ConsoleLogService {
private seed = Math.random();
public log(msg: string) { console.log([this.seed], msg); }
}
const globalInjector = new Injector();
globalInjector.registerService(ConsoleLogService, new ConsoleLogService());
function Inject(target: Object, propertyKey: string): any {
// конструктор типа свойства === ConsoleLogService
const propertyType: Function = Reflect.getMetadata("design:type", target, propertyKey);
const descriptor = {
get: function () {
// можно определять свой инжектор в класс декорируемого свойства,
// чтобы брать сервисы из него (как providers в @Component в Ангуляре)
// либо берем сервисы из корневого инжектора
const injector = this.injector || globalInjector;
return injector.getService(propertyType);
}
};
Object.defineProperty(target, propertyKey, descriptor);
return descriptor;
}
class Component {
public injector;
@Inject
private logService: ConsoleLogService;
sayHello() {
this.logService.log('Hello world');
}
}
const component1 = new Component();
component1.sayHello();
const component2 = new Component();
const localInjector = new Injector();
localInjector.registerService(ConsoleLogService, new ConsoleLogService());
component2.injector = localInjector;
component2.sayHello();
component1.sayHello();
component2.sayHello();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment