javascriptnode.jsnestjsinversifyjs

multiInject in Nest.js


In Inversify.js there is multiInject decorator that allow us to inject multiple objects as array. All objects' dependencies in this array resolved as well.

Is there any way to achieve this in Nest.js?


Solution

  • There is no direct equivalent to multiInject. You can provide an array with a custom provider though:

    Example

    Try the example live in this sandbox.

    Injectables

    Let's assume you have multiple @Injectable classes that implement the interface Animal.

    export interface Animal {
      makeSound(): string;
    }
    
    @Injectable()
    export class Cat implements Animal {
      makeSound(): string {
        return 'Meow!';
      }
    }
    
    @Injectable()
    export class Dog implements Animal {
      makeSound(): string {
        return 'Woof!';
      }
    }
    

    Module

    The classes Cat and Dog are both available in your module (provided there or imported from another module). Now you create a custom token for the array of Animal:

    providers: [
        Cat,
        Dog,
        {
          provide: 'MyAnimals',
          useFactory: (cat, dog) => [cat, dog],
          inject: [Cat, Dog],
        },
      ],
    

    Controller

    You can then inject and use the Animal array in a Controller like this:

    constructor(@Inject('MyAnimals') private animals: Animal[]) {
      }
    
    @Get()
    async get() {
      return this.animals.map(a => a.makeSound()).join(' and ');
    }
    

    This also works if Dog has additional dependencies like Toy, as long as Toy is available in the module (imported/provided):

    @Injectable()
    export class Dog implements Animal {
      constructor(private toy: Toy) {
      }
      makeSound(): string {
        this.toy.play();
        return 'Woof!';
      }
    }