NestJs providers

91 阅读1分钟

1. Declare a provider

  1. 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:

DEFAULTA 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.
REQUESTA new instance of the provider is created exclusively for each incoming request. The instance is garbage-collected after the request has completed processing.
TRANSIENTTransient 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 {}
  1. Standard
providers: [
  {
    provide: CatsService,
    useClass: CatsService,
  },
];
  1. Value
import { CatsService } from './cats.service';

const mockCatsService = {
  /* mock implementation
  ...
  */
};

@Module({
  imports: [CatsModule],
  providers: [
    {
      provide: CatsService,
      useValue: mockCatsService,
    },
  ],
})
export class AppModule {}
  1. class providers
const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}
  1. Factory providers
  2. Alias providers
@Injectable()
class LoggerService {
  /* implementation details */
}

const loggerAliasProvider = {
  provide: 'AliasedLoggerService',
  useExisting: LoggerService,
};

@Module({
  providers: [LoggerService, loggerAliasProvider],
})
export class AppModule {}