Reputation: 524
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
Upvotes: 12
Views: 17723
Reputation: 351
I'm using GraphQL and my resolver is decorated with @Resolver()
,
so I had to not use @Dependencies
(since I got a TypeError, that my functions are not functions).
I exported my service:
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserResolver } from './user.resolver';
@Module({
providers: [UserResolver, UserService],
exports: [UserService], //This line is new
})
export class UserModule {}
Then, I imported it in the other module:
import { Module } from '@nestjs/common';
import { IngredientService } from './ingredient.service';
import { IngredientResolver } from './ingredient.resolver';
import { UserModule } from 'src/user/user.module'; //This line is new
@Module({
providers: [IngredientResolver, IngredientService],
imports: [UserModule], //This line is new
})
export class IngredientModule {}
Then, in my resolver, I added it in the constructor:
import { UserService } from 'src/user/user.service'; //This line is new
@Resolver(() => Ingredient)
export class IngredientResolver {
constructor(
private readonly ingredientService: IngredientService,
private readonly userService: UserService, //This line is new
) {}
Upvotes: 0
Reputation: 316
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.
Upvotes: 7
Reputation: 2720
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
).
Upvotes: 3