NestJS: Use a solo @injectable class as a singleton Provider
220318
Intro
NestJS Modules are Singletons by default. Their Providers are also singletons when they are provided from within the same module. However, there are cases where we want to use just a single solo class as provider to a couple or more modules. In such cases we can use the solo class as singleton or not. Let’s see how we can do that.
The case
Let’s get again the ‘classic’ case, where we have the 2 Modules: AuthModule and UsersModule. And suppose we want to use the DbRepo class as a singleton Provider. The AuthModule should have precedence over the UsersModule, since we use only authenticated users.
An incoming request has to options:
- It should have passed via the Sign-In process in order to be authorized (e.g. obtain a JWT token) via AuthModule –> AuthController – Sign-Up.
OR
- It can have free access to create a new user, again via AuthModule –> AuthController – Sign-In.
The @injectable DbRepo serves (provides data to and interacts with) both: the AuthServise, and UsersService. So, each one of those services has to have the DbRepo injected into its constructor.
constructor(private dbRepo: DbRepo) {}
The UsersModule, has to add the AuthModule in its imports section array, in any case.
This NOT a singleton approach
This is when we add the DbRepo into the providers array section of the AuthModule and UsersModule, separately (independently):
AuthModule
UsersModule
In such an approach each module creates its very own instance of DbRepo, and thus this is not Singleton. If, for example you create a new user (AuthModule –> AuthController –> signup), then there is no way to reflect this user in UsersModule (e.g. UsersModule –> UsersController –> getusers)
The singleton approach
The DbRepo should not be added to both of the Modules. It has to be added only to the module that has the precedence, i.e., the AuthModule. And, it also has to be exported. That way any other module, that imports the AuthModule, can immediately use the exported providers – the DbRepo in our case.
AuthModule
UsersModule
Then, the UsersModule has to do nothing. Since it imports the AuthModule, any provider/service in the UsersModule, can access the singleton instance of DbRepo provided and exported from the AuthModule.
That’s it!
I hope you enjoyed it! Happy coding!