Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Kamil Mysliwiec

January 11, 2019
Tweet

More Decks by Kamil Mysliwiec

Other Decks in Programming

Transcript

  1. KAMMYSLIWIEC
    DEPENDENCY INJECTION 

    IN NEST AND ANGULAR:
    INTERSECTION & MISMATCH

    View full-size slide

  2. KAMMYSLIWIEC
    KAMIL MYSLIWIEC
    SOFTWARE ENGINEER 

    CONSULTANT & TRAINER


    CREATOR OF NESTJS
    @KAMMYSLIWIEC


    View full-size slide

  3. KAMIL MYŚLIWIEC
    SOFTWARE ENGINEER

    @KAMMYSLIWIEC


    View full-size slide

  4. KAMMYSLIWIEC
    Adonis Express Koa Nest Fastify

    View full-size slide

  5. NESTJS
    WWW.NESTJS.COM

    @NESTFRAMEWORK

    KAMMYSLIWIEC

    View full-size slide

  6. DEPENDENCY
    INJECTION

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  12. KAMMYSLIWIEC
    COMPILER 

    METADATA

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  19. REFLECTION

    API

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  24. KAMMYSLIWIEC
    ENQUIRER INJECTOR
    CONTAINER
    KEY
    VALUE

    View full-size slide

  25. KAMMYSLIWIEC
    BEHIND
    FRAMEWORKS

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  30. KAMMYSLIWIEC
    REFLECTION API

    CHALLENGES

    View full-size slide

  31. KAMMYSLIWIEC
    INTERFACES

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  34. KAMMYSLIWIEC
    const metadata = Reflect.getMetadata(
    ‘design:paramtypes',
    CatsService,
    );
    // metadata = [Object, Logger]

    // IHttpService === Object

    View full-size slide

  35. KAMMYSLIWIEC
    POTENTIAL 

    SOLUTION

    View full-size slide

  36. KAMMYSLIWIEC
    GENERICS

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  39. KAMMYSLIWIEC
    const metadata = Reflect.getMetadata(
    ‘design:paramtypes',
    CatsService,
    );
    // metadata = [HttpService, Repository]
    // what about Cat class?

    View full-size slide

  40. KAMMYSLIWIEC
    POTENTIAL 

    SOLUTION

    View full-size slide

  41. KAMMYSLIWIEC
    CIRCULAR

    DEPENDENCIES

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  44. KAMMYSLIWIEC
    const metadata = Reflect.getMetadata(
    ‘design:paramtypes',
    CatsService,
    );
    // metadata = [undefined]
    // DogsService === undefined

    View full-size slide

  45. KAMMYSLIWIEC
    POTENTIAL 

    SOLUTION

    View full-size slide

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

    View full-size slide

  47. KAMMYSLIWIEC
    INJECTOR TREES

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  52. INJECTORS

    IN NEST

    View full-size slide

  53. KAMMYSLIWIEC
    CORE
    USERS
    SHARED
    APPLICATION
    AUTH BLOG

    View full-size slide

  54. KAMMYSLIWIEC

    View full-size slide

  55. KAMMYSLIWIEC
    CORE
    USERS
    SHARED
    APPLICATION
    AUTH BLOG

    View full-size slide

  56. KAMMYSLIWIEC
    CORE
    USERS
    SHARED
    APPLICATION
    AUTH BLOG

    View full-size slide

  57. KAMMYSLIWIEC
    CORE
    USERS
    SHARED
    APPLICATION
    AUTH BLOG

    View full-size slide

  58. KAMMYSLIWIEC
    CORE
    USERS
    SHARED
    APPLICATION
    AUTH BLOG

    View full-size slide

  59. KAMMYSLIWIEC
    CORE
    USERS
    SHARED
    APPLICATION
    AUTH BLOG

    View full-size slide

  60. KAMMYSLIWIEC
    CORE
    USERS
    SHARED
    APPLICATION
    AUTH BLOG

    View full-size slide

  61. KAMMYSLIWIEC
    GLOBAL

    SCOPE

    View full-size slide

  62. KAMMYSLIWIEC
    CORE
    USERS
    SHARED
    APPLICATION
    AUTH BLOG

    View full-size slide

  63. KAMMYSLIWIEC
    CORE
    USERS
    SHARED
    APPLICATION
    AUTH BLOG

    View full-size slide

  64. WHAT’S NEXT

    View full-size slide

  65. KAMMYSLIWIEC
    SCOPES

    View full-size slide

  66. KAMMYSLIWIEC
    REQUEST
    PROVIDER
    REQUEST REQUEST

    View full-size slide

  67. KAMMYSLIWIEC
    REQUEST
    PROVIDER
    REQUEST REQUEST
    PROVIDER PROVIDER

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  70. KAMMYSLIWIEC
    PROVIDER C
    PROVIDER A
    PROVIDER B PROVIDER D
    PROVIDER A PROVIDER A

    View full-size slide

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

    View full-size slide

  72. KAMMYSLIWIEC
    OPEN SOURCE

    View full-size slide

  73. KAMMYSLIWIEC

    View full-size slide

  74. KAMMYSLIWIEC
    KAMMYSLIWIEC
    THANK

    YOU
    @KAMMYSLIWIEC

    [email protected]

    View full-size slide