1. Declare a provider
- use
@Injectable()
The decorator attaches metadata, which declares that CatsService is a class that can be managed by the Nest [IoC]
2.Provider registration
import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class AppModule {}
2.Dependency injection
1. constructor-based
constructor(private catsService: CatsService) {}
constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
2.Property-based injection
@Injectable()
export class HttpService<T> {
@Inject('HTTP_OPTIONS')
private readonly httpClient: T;
}
Scopes (lifetime)
Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully safe for our applications.
But you can custom scope by yourself.
A provider can have any of the following scopes:
DEFAULT | A single instance of the provider is shared across the entire application. The instance lifetime is tied directly to the application lifecycle. Once the application has bootstrapped, all singleton providers have been instantiated. Singleton scope is used by default. |
|---|---|
REQUEST | A new instance of the provider is created exclusively for each incoming request. The instance is garbage-collected after the request has completed processing. |
TRANSIENT | Transient providers are not shared across consumers. Each consumer that injects a transient provider will receive a new, dedicated instance. |
HINT
Using singleton scope is recommended for most use cases. Sharing providers across consumers and across requests means that an instance can be cached and its initialization occurs only once, during application startup.
@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
- Standard
providers: [
{
provide: CatsService,
useClass: CatsService,
},
];
- Value
import { CatsService } from './cats.service';
const mockCatsService = {
/* mock implementation
...
*/
};
@Module({
imports: [CatsModule],
providers: [
{
provide: CatsService,
useValue: mockCatsService,
},
],
})
export class AppModule {}
- class providers
const configServiceProvider = {
provide: ConfigService,
useClass:
process.env.NODE_ENV === 'development'
? DevelopmentConfigService
: ProductionConfigService,
};
@Module({
providers: [configServiceProvider],
})
export class AppModule {}
- Factory providers
- Alias providers
@Injectable()
class LoggerService {
/* implementation details */
}
const loggerAliasProvider = {
provide: 'AliasedLoggerService',
useExisting: LoggerService,
};
@Module({
providers: [LoggerService, loggerAliasProvider],
})
export class AppModule {}