Constructor injection helps you give a class the things it needs to work by passing them in when you create it. This makes your code cleaner and easier to manage.
Constructor injection in NestJS
constructor(private readonly serviceName: ServiceType) {}The constructor is a special method that runs when the class is created.
Using private readonly automatically creates and stores the service as a class property.
UsersService into the class so you can use it inside.constructor(private readonly usersService: UsersService) {}constructor(private readonly logger: LoggerService, private readonly config: ConfigService) {}@Inject() to inject a custom provider by its token.constructor(@Inject('CUSTOM_SERVICE') private readonly customService: CustomService) {}This example shows a HelloService that returns a greeting. The HelloController uses constructor injection to get the service and call its method when handling a GET request.
import { Injectable } from '@nestjs/common'; @Injectable() export class HelloService { getHello(): string { return 'Hello, NestJS!'; } } import { Controller, Get } from '@nestjs/common'; import { HelloService } from './hello.service'; @Controller() export class HelloController { constructor(private readonly helloService: HelloService) {} @Get() getHello(): string { return this.helloService.getHello(); } }
Always mark injected services with private readonly to keep them safe inside the class.
Constructor injection works only if the class is decorated with @Injectable() or a similar decorator.
Use constructor injection to make your classes easier to test by replacing dependencies with mocks.
Constructor injection passes needed services into a class when it is created.
This keeps code clean, organized, and easy to test.
In NestJS, use constructor(private readonly service: ServiceType) inside classes decorated with @Injectable() or @Controller().
Practice
Solution
Step 1: Understand constructor injection concept
Constructor injection is used to pass dependencies (services) into a class automatically when it is created.Step 2: Identify the purpose in NestJS context
In NestJS, constructor injection helps keep code clean by providing needed services without manual instantiation.Final Answer:
To provide required services to a class when it is created -> Option AQuick Check:
Constructor injection = provide services automatically [OK]
- Thinking constructor injection creates routes
- Manually creating service instances inside methods
- Confusing injection with database queries
UsersService in a NestJS class?Solution
Step 1: Check for correct access modifier and typing
In NestJS, constructor injection requiresprivate readonlywith the service type for proper injection and immutability.Step 2: Compare options
constructor(private readonly usersService: UsersService) {}(A) is correct. B misses access modifier, C misses type, D misses type annotation.Final Answer:
constructor(private readonly usersService: UsersService) {} -> Option AQuick Check:
Use private readonly with type for injection [OK]
- Omitting access modifier like private or public
- Not specifying the service type
- Using public readonly without specifying the service type
appController.getHello() is called?import { Injectable, Controller } from '@nestjs/common';
@Injectable()
class HelloService {
getMessage() {
return 'Hello, NestJS!';
}
}
@Controller()
class AppController {
constructor(private readonly helloService: HelloService) {}
getHello() {
return this.helloService.getMessage();
}
}Solution
Step 1: Understand constructor injection usage
TheAppControllerreceivesHelloServicevia constructor injection and stores it ashelloService.Step 2: Trace method call
CallinggetHello()callshelloService.getMessage()which returns 'Hello, NestJS!'.Final Answer:
'Hello, NestJS!' -> Option CQuick Check:
Injected service method returns 'Hello, NestJS!' [OK]
- Assuming service is undefined without injection
- Confusing method return values
- Expecting default or unrelated strings
@Injectable()
class CatsService {}
@Controller('cats')
class CatsController {
constructor(catsService: CatsService) {}
findAll() {
return 'All cats';
}
}Solution
Step 1: Check constructor injection syntax
The constructor parametercatsService: CatsServicelacks an access modifier likeprivateorpublic, so it won't be assigned as a class property.Step 2: Verify other parts
@Injectable()is present on service,@Controller('cats')has path, andfindAllcan be sync. So no other errors.Final Answer:
Missing access modifier (private/public) in constructor parameter -> Option BQuick Check:
Constructor injection needs access modifier [OK]
- Omitting private/public in constructor injection
- Thinking @Injectable is missing when it is present
- Assuming controller path is mandatory for injection
AuthService and UsersService, into a NestJS controller. Which constructor correctly injects both services following best practices?Solution
Step 1: Check for access modifiers and readonly usage
Best practice is to useprivate readonlyfor injected services to keep them immutable and private.Step 2: Verify both services are injected with correct syntax
constructor(private readonly authService: AuthService, private readonly usersService: UsersService) {} injects both services withprivate readonly, while others miss modifiers or use public.Final Answer:
constructor(private readonly authService: AuthService, private readonly usersService: UsersService) {} -> Option DQuick Check:
Use private readonly for multiple injected services [OK]
- Omitting access modifiers on one or both services
- Using public instead of private readonly
- Mixing access modifiers inconsistently
Ready to prove it?
Pass the test and this pattern moves unknown
