Files
2nd/10_Wiki/Topics/Dependency_Injection.md
T
2026-05-02 23:39:17 +09:00

4.7 KiB

category, tags, title, description, last_updated
category tags title description last_updated
Unified
Design Patterns
OOP
SOLID
Software Architecture
Dependency Injection (DI) 객체의 생성과 사용을 분리하고, 필요한 의존성을 외부에서 주입하여 결합도를 낮추는 설계 패턴 2026-05-02

Dependency Injection (DI)

📌 Brief Summary

**의존성 주입(Dependency Injection, DI)**은 객체 지향 프로그래밍에서 객체 간의 결합도를 낮추기 위해 사용되는 설계 패턴입니다. 객체가 내부에서 필요한 의존 객체를 직접 생성(new)하지 않고, 인터페이스를 통해 외부(프레임워크나 컨테이너)로부터 주입받는 방식을 의미합니다. 이는 SOLID 원칙 중 하나인 **의존성 역전 원칙(DIP)**을 실현하는 핵심 메커니즘으로, 코드의 유연성, 재사용성, 그리고 테스트 용이성을 획기적으로 향상시킵니다.


📖 Core Content

1. 주요 주입 방식

  • 생성자 주입 (Constructor Injection): 객체 생성 시점에 의존성을 주입받는 방식으로, 필드를 final/readonly로 유지할 수 있어 불변성을 보장하고 가장 권장되는 방식입니다.
  • 세터 주입 (Setter Injection): 객체 생성 후 세터 메서드를 통해 의존성을 주입합니다. 선택적 의존성이 있거나 실행 중에 변경이 필요할 때 사용합니다.
  • 인터페이스 주입 (Interface Injection): 주입을 담당하는 인터페이스를 통해 의존성을 제공받습니다. (상대적으로 사용 빈도가 낮음)

2. 제어의 역전 (IoC)과의 관계

DI는 **제어의 역전(Inversion of Control)**을 실현하는 구체적인 방법 중 하나입니다. 객체의 생성 주기와 의존성 조립의 권한을 객체 자신이 아닌 외부의 IoC 컨테이너(Spring의 ApplicationContext, NestJS의 Module 등)로 위임함으로써 개발자는 비즈니스 로직에만 집중할 수 있게 됩니다.

3. 실무 설계 패턴 (Frameworks)

  • NestJS: @Injectable()과 모듈 시스템을 통해 강력한 DI 컨테이너를 제공합니다. TypeScript의 타입을 토큰으로 활용하여 의존성을 자동 연결합니다.
  • Spring Boot: @Autowired나 생성자 주입을 통해 Bean 간의 의존성을 관리합니다.
  • Riverpod (Flutter): 상태 관리 기능에 DI를 결합하여 컴파일 타임 안정성을 제공하고 위젯 트리 외부에서 의존성을 안전하게 제공합니다.

⚖️ Trade-offs & Caveats

Benefits

  • 낮은 결합도: 객체 간의 직접적인 참조가 줄어들어 특정 구현체가 변경되어도 이를 사용하는 코드를 수정할 필요가 없습니다.
  • 테스트 용이성: 실제 DB나 API 객체 대신 Mock(가짜) 객체를 외부에서 주입하여 독립적인 단위 테스트가 가능합니다.
  • 유지보수성: 객체의 생성 로직이 한곳(Composition Root)에 모여 있어 시스템 구성 파악이 용이합니다.

⚠️ Challenges

  • 초기 복잡성: 단순한 프로젝트에서는 인터페이스 정의와 프레임워크 설정 등이 오버헤드가 될 수 있습니다 (Overkill).
  • 런타임 오류: 의존성이 런타임에 주입되므로, 설정 오류로 인한 주입 실패를 컴파일 시점에 발견하기 어려울 수 있습니다 (단, 최신 프레임워크는 이를 상당 부분 개선함).
  • 코드 추적의 어려움: 객체 생성 로직이 외부에 감추어져 있어, 코드를 처음 읽는 개발자가 실제 어떤 클래스가 사용되는지 파악하기 위해 미로를 헤매는 현상(The Hidden Maze)이 발생할 수 있습니다.

🔗 Knowledge Connections

Practical Application Contexts

  • Unit Testing: 테스트 환경에서 Mock Repository를 주입하여 비즈니스 로직을 검증합니다.
  • Polyglot Infrastructure: 설정 파일만 변경하여 SQL DB 어댑터를 NoSQL DB 어댑터로 교체합니다.

💡 Adjacent Topics

  • NestJS: DI를 기반으로 아키텍처를 강제하는 대표적인 Node.js 프레임워크입니다.
  • Composition_Root: 애플리케이션 진입점에서 모든 객체 의존성을 조립하는 지점입니다.
  • Service_Locator_Pattern: DI와 유사하지만 객체가 직접 저장소를 호출하여 의존성을 찾는, 지양해야 할 안티패턴입니다.

Last updated: 2026-05-02