You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Injector.ts 1.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import 'reflect-metadata';
  2. import { Type } from './Util';
  3. import { FrontworkComponent } from '../Types/FrontworkComponent';
  4. /**
  5. * The Injector stores services and resolves requested instances.
  6. */
  7. export const Injector = new class {
  8. injectionQueue :any[] = []
  9. rootInterface : Type<any>
  10. root : Type<any>
  11. rootModules: Type<any>[] = []
  12. modules : {implements?: Type<any>, implementation: Type<any>}[] = []
  13. moduleObjs : {[key in string] : FrontworkComponent} = {}
  14. /**
  15. * Resolves instances by injecting required services
  16. * @param {Type<any>} target
  17. * @returns {T}
  18. */
  19. resolve<T>(target: Type<any>): T {
  20. // tokens are required dependencies, while injections are resolved tokens from the Injector
  21. if(this.moduleObjs[target.name])
  22. return this.moduleObjs[target.name] as any
  23. if(target.name === this.rootInterface.name || target.name === this.root.name){
  24. let modules = this.modules.map(m => {
  25. const module = new m.implementation()
  26. if(m.implements)
  27. this.moduleObjs[m.implements.name] = module
  28. this.moduleObjs[m.implementation.name] = module
  29. return module
  30. })
  31. const rootobj = new this.root(modules);
  32. this.moduleObjs[this.rootInterface.name] = rootobj
  33. this.moduleObjs[target.name] = rootobj
  34. while(this.injectionQueue.length > 0){
  35. const i = this.injectionQueue.shift()
  36. if(this.moduleObjs[i.what.name])
  37. i.target[i.where] = this.moduleObjs[i.what.name]
  38. else
  39. this.injectionQueue.push(i)
  40. }
  41. return rootobj
  42. }
  43. this.moduleObjs[target.name] = new target()
  44. return this.moduleObjs[target.name] as any
  45. }
  46. };