Що робить IoC-контейнер в NestJS?
Що таке IoC-контейнер в NestJS
IoC-контейнер (Inversion of Control Container) в NestJS - це механізм, який керує створенням, зберіганням і впровадженням залежностей (провайдерів) у застосунку. Він реалізує принцип Inversion of Control - тобто інверсію управління: → ти не створюєш об'єкти вручну, а доручаєш це фреймворку.
Простими словами
Без IoC-контейнера ти писав би так:
javascript
const usersService = new UsersService();
const usersController = new UsersController(usersService);З IoC-контейнером Nest робить це автоматично: достатньо вказати залежності в конструкторі:
javascript
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
}Nest сам:
- створює екземпляр
UsersService; - зберігає його в DI-контейнері;
- впроваджує його в
UsersController.
Як працює IoC-контейнер покроково
- Сканує модулі (
@Module()) і збирає список усіхproviders,controllersіimports. - Реєструє провайдери в контейнері (за токеном - зазвичай це сам клас чи рядковий ідентифікатор).
- Створює екземпляри провайдерів (за замовчуванням - один спільний екземпляр, Singleton).
- Відстежує залежності і впроваджує їх при створенні інших класів.
- Зберігає посилання на вже створені екземпляри, щоб перевикористовувати їх при повторних запитах.
Приклад наочно
javascript
@Injectable()
export class UsersService {
findAll() {
return ['John', 'Alex'];
}
}
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}
@Get()
getUsers() {
return this.usersService.findAll();
}
}
@Module({
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}Що робить IoC-контейнер:
- Бачить
UsersModule. - Реєструє
UsersServiceяк провайдер. - Створює екземпляр
UsersServiceі зберігає його. - При створенні
UsersControllerбачить, що в конструкторі потрібенUsersService. - Впроваджує (інжектує) готовий екземпляр.
Ключова ідея - інверсія управління
Зазвичай:
Ти створюєш залежності вручну.
З IoC:
Ти просто оголошуєш, що тобі потрібно - контейнер сам вирішує, як це створити.
Переваги IoC-контейнера в NestJS
| Перевага | Пояснення |
|---|---|
| Послаблена зв'язаність | Класи не залежать напряму від реалізації залежностей. |
| Перевикористання | Один екземпляр провайдера можна використовувати в багатьох місцях. |
| Легке тестування | Можна підмінити залежності моками. |
| Автоматичне керування життєвим циклом | Nest сам створює, кешує й знищує екземпляри. |
| Гнучкість | Можна перевизначати провайдери (useClass, useValue, useFactory). |
Внутрішні деталі (якщо цікаво)
- Кожен модуль має свій IoC-контейнер (власну область видимості).
- Контейнери можуть успадковувати залежності з імпортованих модулів.
- При пошуку залежності Nest йде "вгору по дереву модулів", поки не знайде потрібний провайдер.
Приклад з токенами й фабриками
javascript
@Module({
providers: [
{
provide: 'RANDOM',
useFactory: () => Math.random(),
},
],
})
export class AppModule {}
@Injectable()
export class ExampleService {
constructor(@Inject('RANDOM') private random: number) {}
log() {
console.log(this.random);
}
}IoC-контейнер:
- реєструє
'RANDOM'як токен; - викликає фабрику
useFactory; - зберігає результат;
- при створенні
ExampleServiceвпроваджує значенняrandom.
Візуальна схема роботи IoC
javascript
┌────────────────────┐
│ @Module() │
│ imports, providers │
└───────┬────────────┘
│
▼
┌──────────────────────────┐
│ IoC-контейнер NestJS │
│ - Реєструє провайдери │
│ - Створює екземпляри │
│ - Керує залежностями │
└───────────┬──────────────┘
│
▼
┌────────────────────────┐
│ Контролер / Сервіс │
│ → отримує залежності │
│ через конструктор │
└────────────────────────┘Підсумок
| Термін | Пояснення |
|---|---|
| IoC-контейнер | Система, що керує залежностями (Dependency Injection) |
| Завдання | Створювати, зберігати й впроваджувати провайдери |
| Принцип | Інверсія управління: об'єкт не створює залежності сам |
| Переваги | Послаблена зв'язаність, перевикористання, тестованість |
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.