I have custom module AuthModule
with AuthService
, AuthController
with routes and so on, that work fine, and want to share this module between several projects as a package. The questions is how to extend imported AuthService
from this package and how to inject in it additional services?
More details
Into my custom AuthService
, that I want to place in package, is injected class UserService
, that by default gets from the database some User
data and return it to client side . I need to inject into AuthService
another, for example ProfileService
from application, that get from database User
extra data. The aim is to merge User
main data and User
extra data, and return this bunch to client
Dependency injection is an inversion of control (IoC) technique wherein you delegate instantiation of dependencies to the IoC container (in our case, the NestJS runtime system), instead of doing it in your own code imperatively.
@Injectable() is how you tell Nest this is a class that can have dependencies that should be instantiated by Nest and its DI system. The code you posted works because there are no injected dependencies.
Service. In enterprise applications, we follow the SOLID principle, where S stands for Single Responsibility . The controllers are responsible for accepting HTTP requests from the client and providing a response. For providing the response, you may need to connect to some external source for data.
A DTO is an object that defines how the data will be sent over the network. We could determine the DTO schema by using TypeScript interfaces, or by simple classes. Interestingly, we recommend using classes here.
I don't see really the need for a Dynamic Module here.
Indeed, only is needed that the service you want to inject into other entity managed by NestJs, is exported from your AuthModule, and AuthModule imported in the Module you want other entities have injected your AuthService.
import { Module } from '@nestjs/common'
import { AuthService } from './AuthService'
@Module({
providers: [
AuthService,
// ... others
],
exports: [
AuthService
]
})
export class CommonModule {}
Then in your dependent class (let's say another Controller, but could be anything like a GraphQL Resolver, Interceptor, or whatever), you declare the dependency on AuthService.
import { AuthService } from '../auth/AuthService'
import { Dependencies } from '@nestjs/common'
@Dependencies(AuthService)
export class DependentController {
constructor (authService) {
this.authService = authService
}
}
Finally, in order to the AuthService be available to the dependent controller, it has to be imported in the same Module that controller is provided.
import { Module } from '@nestjs/common'
import { CommonModule } from '../auth/CommonModule'
import { DependentController } from './controller/DependentController'
@Module({
imports: [
CommonModule,
// ...others
],
providers: [
DependentController,
// ...others
]
})
export class ControllerModule {}
I understand that the syntax could be shorter and without using Dependencies decorator in typescript, however the core of the matter is exporting the shared Service from the Module it is provided, then importing that module into the Module other classes that require it.
This is one of the use cases Dynamic Modules have been created for.
import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';
@Module({
providers: [Connection],
})
export class DatabaseModule {
static forRoot(entities = [], options?): DynamicModule {
const providers = createDatabaseProviders(options, entities);
return {
module: DatabaseModule,
providers: providers,
exports: providers,
};
}
}
In this example, see how providers
are given (dynamically) to the result module.
Your package should follow the same pattern: expose a static method which allows building a DynamicModule
, so you can resolve your other services (internal or external) as you want (building your own array of providers
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With