# All files / core/injector instance-loader.ts

100% Statements 36/36
100% Branches 0/0
100% Functions 22/22
100% Lines 36/36

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    911x

    1x

    1x

    1x
    4x
    4x

    4x

    4x

    4x
    4x

    4x
    4x
    4x
    4x

    4x
    4x
    4x
    4x
    4x

    4x
    4x

    4x
    2x

    4x
    2x
    2x

    4x
    2x

    4x
    2x
    2x

    4x
    1x

    4x
    1x
    1x

     import { Logger } from '@nestjs/common';
    import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
    import { Injectable } from '@nestjs/common/interfaces/injectable.interface';
    import { MODULE_INIT_MESSAGE } from '../helpers/messages';
    import { NestContainer } from './container';
    import { Injector } from './injector';
    import { Module } from './module';

    export class InstanceLoader {
      private readonly injector = new Injector();
      private readonly logger = new Logger(InstanceLoader.name, true);

      constructor(private readonly container: NestContainer) {}

      public async createInstancesOfDependencies() {
        const modules = this.container.getModules();

        this.createPrototypes(modules);
        await this.createInstances(modules);
      }

      private createPrototypes(modules: Map<string, Module>) {
        modules.forEach(module => {
          this.createPrototypesOfComponents(module);
          this.createPrototypesOfInjectables(module);
          this.createPrototypesOfRoutes(module);
        });
      }

      private async createInstances(modules: Map<string, Module>) {
        await Promise.all(
          [...modules.values()].map(async module => {
            await this.createInstancesOfComponents(module);
            await this.createInstancesOfInjectables(module);
            await this.createInstancesOfRoutes(module);

            const { name } = module.metatype;
            this.logger.log(MODULE_INIT_MESSAGE`${name}`);
          }),
        );
      }

      private createPrototypesOfComponents(module: Module) {
        module.components.forEach(wrapper => {
          this.injector.loadPrototypeOfInstance<Injectable>(
            wrapper,
            module.components,
          );
        });
      }

      private async createInstancesOfComponents(module: Module) {
        await Promise.all(
          [...module.components.values()].map(async wrapper =>
            this.injector.loadInstanceOfComponent(wrapper, module),
          ),
        );
      }

      private createPrototypesOfRoutes(module: Module) {
        module.routes.forEach(wrapper => {
          this.injector.loadPrototypeOfInstance<Controller>(wrapper, module.routes);
        });
      }

      private async createInstancesOfRoutes(module: Module) {
        await Promise.all(
          [...module.routes.values()].map(async wrapper =>
            this.injector.loadInstanceOfRoute(wrapper, module),
          ),
        );
      }

      private createPrototypesOfInjectables(module: Module) {
        module.injectables.forEach(wrapper => {
          this.injector.loadPrototypeOfInstance<Controller>(
            wrapper,
            module.injectables,
          );
        });
      }

      private async createInstancesOfInjectables(module: Module) {
        await Promise.all(
          [...module.injectables.values()].map(async wrapper =>
            this.injector.loadInstanceOfInjectable(wrapper, module),
          ),
        );
      }
    }