Dependency Injection in Nest and Angular: Intersection & Mismatch

Dependency Injection in Nest and Angular: Intersection & Mismatch

Dependency Injection framework is a core and inherent feature of both Nest and Angular. DI simplifies creating scalable, testable, and maintainable applications by giving us flexible and efficient abstractions. However, did we ever think how this mechanism works underneath? In this talk, we’ll compare how Nest and Angular DI systems differ from each other as well as dive into the basics of the metadata reflection API in TypeScript.

2c6d09f60e512f388508afe9bebfcd6f?s=128

Kamil Mysliwiec

January 11, 2019
Tweet

Transcript

  1. KAMMYSLIWIEC DEPENDENCY INJECTION 
 IN NEST AND ANGULAR: INTERSECTION &

    MISMATCH
  2. KAMMYSLIWIEC KAMIL MYSLIWIEC SOFTWARE ENGINEER 
 CONSULTANT & TRAINER
 


    CREATOR OF NESTJS @KAMMYSLIWIEC

  3. KAMIL MYŚLIWIEC SOFTWARE ENGINEER
 @KAMMYSLIWIEC


  4. KAMMYSLIWIEC Adonis Express Koa Nest Fastify

  5. NESTJS WWW.NESTJS.COM
 @NESTFRAMEWORK
 KAMMYSLIWIEC

  6. DEPENDENCY INJECTION

  7. KAMMYSLIWIEC @Injectable() class CatsService { private httpService = new HttpService();

    private logger = new Logger(); }
  8. KAMMYSLIWIEC @Injectable() class CatsService { private httpService = new HttpService();

    private logger = new Logger(); }
  9. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private httpService: HttpService, private

    logger: Logger, ) {} }
  10. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private httpService: HttpService, private

    logger: Logger, ) {} }
  11. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private httpService: HttpService, private

    logger: Logger, ) {} }
  12. KAMMYSLIWIEC COMPILER 
 METADATA

  13. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private httpService: HttpService, private

    logger: Logger, ) {} }
  14. KAMMYSLIWIEC CatsService = __decorate( [__metadata('design:paramtypes', [HttpService, Logger])], CatsService, );

  15. KAMMYSLIWIEC CatsService = __decorate( [__metadata('design:paramtypes', [HttpService, Logger])], CatsService, );

  16. KAMMYSLIWIEC CatsService = __decorate( [__metadata('design:paramtypes', [HttpService, Logger])], CatsService, );

  17. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private httpService: HttpService, private

    logger: Logger, ) {} }
  18. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private httpService: HttpService, private

    logger: Logger, ) {} }
  19. REFLECTION
 API

  20. KAMMYSLIWIEC Reflect.getMetadata('design:paramtypes', CatsService);

  21. KAMMYSLIWIEC Reflect.getMetadata('design:paramtypes', CatsService);

  22. KAMMYSLIWIEC Reflect.getMetadata('design:paramtypes', CatsService);

  23. KAMMYSLIWIEC const metadata = Reflect.getMetadata( ‘design:paramtypes', CatsService, ); // metadata

    = [HttpService, Logger]
  24. KAMMYSLIWIEC ENQUIRER INJECTOR CONTAINER KEY VALUE

  25. KAMMYSLIWIEC BEHIND FRAMEWORKS

  26. KAMMYSLIWIEC CatsService = __decorate( [__metadata('design:paramtypes', [HttpService, Logger])], CatsService, );

  27. KAMMYSLIWIEC CatsService = tslib_1.__decorate( [tslib_1.__metadata( 'design:paramtypes', [HttpService, Logger], )], CatsService,

    );
  28. KAMMYSLIWIEC i1.ɵdid( 1, 4308992, null, 0, i13.HomepageComponent, [i1.ChangeDetectorRef, i7.Router], null,

    null, );
  29. KAMMYSLIWIEC i1.ɵdid( 1, 4308992, null, 0, i13.HomepageComponent, [i1.ChangeDetectorRef, i7.Router], null,

    null, );
  30. KAMMYSLIWIEC REFLECTION API
 CHALLENGES

  31. KAMMYSLIWIEC INTERFACES

  32. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private httpService: HttpService, private

    logger: Logger, ) {} }
  33. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private httpService: IHttpService, private

    logger: Logger, ) {} }
  34. KAMMYSLIWIEC const metadata = Reflect.getMetadata( ‘design:paramtypes', CatsService, ); // metadata

    = [Object, Logger]
 // IHttpService === Object
  35. KAMMYSLIWIEC POTENTIAL 
 SOLUTION

  36. KAMMYSLIWIEC GENERICS

  37. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private httpService: HttpService, private

    logger: Logger, ) {} }
  38. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private httpService: HttpService, private

    catsRepository: Repository<Cat>, ) {} }
  39. KAMMYSLIWIEC const metadata = Reflect.getMetadata( ‘design:paramtypes', CatsService, ); // metadata

    = [HttpService, Repository] // what about Cat class?
  40. KAMMYSLIWIEC POTENTIAL 
 SOLUTION

  41. KAMMYSLIWIEC CIRCULAR
 DEPENDENCIES

  42. KAMMYSLIWIEC @Injectable() class CatsService { constructor( private dogsService: DogsService, )

    {} }
  43. KAMMYSLIWIEC @Injectable() class DogsService { constructor( private catsService: CatsService, )

    {} }
  44. KAMMYSLIWIEC const metadata = Reflect.getMetadata( ‘design:paramtypes', CatsService, ); // metadata

    = [undefined] // DogsService === undefined
  45. KAMMYSLIWIEC POTENTIAL 
 SOLUTION

  46. KAMMYSLIWIEC @Injectable() class CatsService { constructor( @Inject(forwardRef(() => DogsService)) private

    dogsService: DogsService, ) {} }
  47. KAMMYSLIWIEC INJECTOR TREES

  48. KAMMYSLIWIEC ROOT A B C COMPONENT A COMPONENT B COMPONENT

    C @Component({}) export class CmpC { constructor(private c: C) {} }
  49. KAMMYSLIWIEC ROOT A B C COMPONENT A COMPONENT B COMPONENT

    C @Component({}) export class CmpC { constructor(private c: C) {} }
  50. KAMMYSLIWIEC ROOT A B C COMPONENT A COMPONENT B COMPONENT

    C @Component({}) export class CmpC { constructor(private c: C) {} }
  51. KAMMYSLIWIEC ROOT A B C COMPONENT A COMPONENT B COMPONENT

    C @Component({}) export class CmpC { constructor(private c: C) {} }
  52. INJECTORS
 IN NEST

  53. KAMMYSLIWIEC CORE USERS SHARED APPLICATION AUTH BLOG

  54. KAMMYSLIWIEC

  55. KAMMYSLIWIEC CORE USERS SHARED APPLICATION AUTH BLOG

  56. KAMMYSLIWIEC CORE USERS SHARED APPLICATION AUTH BLOG

  57. KAMMYSLIWIEC CORE USERS SHARED APPLICATION AUTH BLOG

  58. KAMMYSLIWIEC CORE USERS SHARED APPLICATION AUTH BLOG

  59. KAMMYSLIWIEC CORE USERS SHARED APPLICATION AUTH BLOG

  60. KAMMYSLIWIEC CORE USERS SHARED APPLICATION AUTH BLOG

  61. KAMMYSLIWIEC GLOBAL
 SCOPE

  62. KAMMYSLIWIEC CORE USERS SHARED APPLICATION AUTH BLOG

  63. KAMMYSLIWIEC CORE USERS SHARED APPLICATION AUTH BLOG

  64. WHAT’S NEXT

  65. KAMMYSLIWIEC SCOPES

  66. KAMMYSLIWIEC REQUEST PROVIDER REQUEST REQUEST

  67. KAMMYSLIWIEC REQUEST PROVIDER REQUEST REQUEST PROVIDER PROVIDER

  68. KAMMYSLIWIEC @Injectable({ scope: Scope.REQUEST }) class CatsService { constructor( private

    httpService: HttpService, private logger: Logger, ) {} }
  69. KAMMYSLIWIEC @Injectable({ scope: Scope.REQUEST }) class CatsService { constructor( private

    httpService: HttpService, private logger: Logger, ) {} }
  70. KAMMYSLIWIEC PROVIDER C PROVIDER A PROVIDER B PROVIDER D PROVIDER

    A PROVIDER A
  71. KAMMYSLIWIEC @Injectable({ scope: Scope.TRANSIENT }) class CatsService { constructor( private

    httpService: HttpService, private logger: Logger, ) {} }
  72. KAMMYSLIWIEC OPEN SOURCE

  73. KAMMYSLIWIEC

  74. KAMMYSLIWIEC KAMMYSLIWIEC THANK
 YOU @KAMMYSLIWIEC
 MAIL@KAMILMYSLIWIEC.COM