NestJS / / 2024. 11. 6. 17:01

NestJS DI(Dependency Injection)

의존성 주입

그림 설명

  1. Class A:
    • 클래스 A는 생성자(constructor)를 통해 클래스 B의 인스턴스를 주입받습니다.
    • 즉, A의 생성자는 B 타입의 instance라는 매개변수를 요구하고 있습니다.
  2. Class B:
    • 클래스 BA가 의존하는 클래스입니다.
    • 여기서 BA의 동작에 필요한 외부 의존성을 제공합니다.

DI(Dependency Injection) 작동 원리

  • 의존성 주입(Dependency Injection, DI)은 객체가 자신의 의존성을 스스로 생성하지 않고 외부에서 제공받는 설계 패턴입니다.
  • 이 그림에서 A 클래스는 B 클래스의 인스턴스를 필요로 하지만, AB 인스턴스를 직접 생성하지 않습니다.
  • 대신, 외부에서 B의 인스턴스를 생성하여 A의 생성자에 주입합니다.

DI의 동작 방식

  1. 인스턴스 생성 순서:
    • A 클래스의 인스턴스를 생성하려고 할 때, A의 생성자에 B 타입의 인스턴스가 필요합니다.
    • 따라서 A의 생성자가 호출되기 전에 B의 생성자가 먼저 호출되어 B의 인스턴스를 만듭니다.
    • 그 후 A의 생성자가 호출되고, B의 인스턴스가 A의 생성자에 주입됩니다.
  2. 주입 후 동작:
    • A 클래스는 주입받은 B의 인스턴스를 통해 B가 제공하는 기능을 사용할 수 있습니다.
    • A 클래스는 B의 내부 로직에 대해 알 필요가 없고, B의 인터페이스나 공개된 메서드만 사용합니다.

의존성 주입의 장점

  • 결합도 감소: AB는 느슨하게 결합됩니다. AB의 구체적인 구현에 의존하지 않고 인터페이스(혹은 타입)에만 의존합니다.
  • 유연성 향상: B의 다른 구현체로 쉽게 교체할 수 있습니다. 예를 들어 B의 테스트용 모의 객체(mock)나 다른 버전의 B 인스턴스를 주입할 수 있습니다.
  • 테스트 용이성: AB의 인스턴스를 독립적으로 테스트할 수 있습니다. A를 테스트할 때 B의 모의 객체를 주입해 A만의 동작을 검증할 수 있습니다.

NestJS와 DI

NestJS는 의존성 주입을 강력히 지원하는 프레임워크로, 주로 데코레이터(@Injectable, @Inject 등)를 통해 의존성을 주입합니다. NestJS에서는 의존성 주입 컨테이너가 B의 인스턴스를 관리하고, 필요 시 자동으로 A의 생성자에 주입하는 방식으로 DI를 지원합니다.

이러한 구조 덕분에 코드의 유연성과 재사용성이 높아지며, 특히 대규모 애플리케이션에서 유지보수가 쉬워집니다.

Inversion of Control(역제어)



이 다이어그램은 Inversion of Control(IoC) 개념을 설명하기 위한 예시입니다. IoC는 제어의 역전이라는 뜻으로, 객체 간의 의존성 관리를 직접 하지 않고 외부에서 주입받도록 하는 방식을 의미합니다. IoC는 의존성 주입(DI)이라는 메커니즘을 통해 구현되는 경우가 많으며, 객체 간의 결합도를 낮추고, 테스트와 유지보수를 쉽게 만듭니다.

다이어그램 설명

  1. Class B:
    • Class BClass AClass C에서 필요한 의존성(dependency)입니다. 즉, Class A와 Class C가 Class B에 의존하고 있습니다.
    • 예를 들어, Class B는 특정 기능을 제공하는 서비스 클래스일 수 있습니다.
  2. Class A와 Class C:
    • Class AClass C는 모두 Class B의 인스턴스가 필요합니다. 두 클래스는 생성자(constructor)를 통해 Class B의 인스턴스를 주입받고 있습니다.
    • 여기서 instance: BClass AClass CClass B의 인스턴스를 의존성으로 받아들이는 부분입니다.

Inversion of Control (제어의 역전)이란?

IoC는 객체 간의 의존성 관리의 책임을 외부로 넘기는 방식입니다. 예를 들어, Class AClass CClass B의 인스턴스를 직접 생성하지 않고, 외부에서 주입받아 사용하게 됩니다.

이 접근 방식은 제어 흐름의 주도권이 객체 내부에서 외부로 넘어가는 것을 의미합니다. 보통 외부에 있는 IoC 컨테이너DI 프레임워크가 필요한 인스턴스를 주입해주는 역할을 합니다.

IoC의 장점

  • 결합도 감소: Class AClass CClass B의 인스턴스를 직접 생성하지 않으므로, 결합도가 낮아져 더 유연한 설계가 가능합니다.
  • 테스트 용이성: 의존성 객체를 외부에서 주입받기 때문에, 테스트용 가짜 객체(mock)를 주입하여 독립적인 단위 테스트가 용이합니다.
  • 유지보수성 증가: 새로운 의존성으로 변경할 때 코드 수정이 최소화되어, 유지보수가 더 쉬워집니다.

IoC와 DI의 관계

IoC는 개념적인 패러다임이고, DI(Dependency Injection)는 이를 구현하는 구체적인 방법 중 하나입니다. DI는 객체가 의존성을 외부에서 주입받도록 하여 IoC를 실현합니다.

예제 코드 (TypeScript)

아래 예제에서 Class B는 외부에서 Class AClass C에 주입되는 의존성입니다.

class B {
  sayHello() {
    console.log("Hello from Class B!");
  }
}

class A {
  constructor(private instance: B) {}

  useB() {
    this.instance.sayHello();
  }
}

class C {
  constructor(private instance: B) {}

  useB() {
    this.instance.sayHello();
  }
}

// IoC 컨테이너 역할const bInstance = new B();
const aInstance = new A(bInstance);
const cInstance = new C(bInstance);

aInstance.useB();// "Hello from Class B!"
cInstance.useB();// "Hello from Class B!"
  • 설명:
    • BsayHello라는 메서드를 가진 간단한 클래스입니다.
    • ACB의 인스턴스를 생성자가 아닌 외부에서 주입받아 사용합니다.
    • bInstanceB의 인스턴스이며, 이를 AC의 인스턴스로 주입하여 사용합니다.

결론

이 다이어그램과 예제는 의존성 객체를 외부에서 주입받아 사용하는 IoC의 개념을 설명합니다. IoC를 통해 객체 간의 결합도를 낮추고 유연성을 높일 수 있으며, NestJS와 같은 프레임워크에서는 IoC를 기반으로 자동으로 의존성을 주입하여 코드의 가독성과 유지보수성을 크게 향상시킵니다.



이 그림은 Inversion of Control(IoC)Dependency Injection(DI)가 NestJS에서 어떻게 적용되는지를 설명하는 다이어그램입니다. 여기서 IoC와 DI의 개념을 기반으로, NestJS의 IoC 컨테이너가 의존성을 관리하고, 필요한 객체를 자동으로 주입하는 방식이 잘 드러나 있습니다.

다이어그램 설명

  1. NestJS IoC 컨테이너:
    • IoC 컨테이너는 NestJS에서 의존성을 관리하고 필요한 객체 인스턴스를 생성하여 주입해주는 역할을 합니다.
    • 여기서 IoC 컨테이너class B, class A, class C인스턴스를 생성하고, 각 클래스의 의존성을 자동으로 주입해줍니다.
    • new B()와 같이 IoC 컨테이너가 필요한 인스턴스를 직접 생성해줍니다.
  2. Class A와 Class C:
    • Class AClass C는 모두 생성자(constructor)를 통해 Class B의 인스턴스를 의존성으로 받아들입니다. 이로 인해 Class AClass CClass B의 구체적인 생성 방법을 알 필요가 없습니다.
    • Class AClass CClass B의 인스턴스에 의존하고 있지만, 직접 생성하지 않고 IoC 컨테이너를 통해 주입받습니다.
  3. 의존성 주입 (Dependency Injection, DI):
    • Class BClass AClass C가 필요로 하는 의존성(Dependency)입니다. 이 의존성은 NestJS IoC 컨테이너에 의해 자동으로 주입됩니다.
    • 즉, Class AClass C가 필요로 하는 Class B의 인스턴스를 IoC 컨테이너가 생성하고 관리하면서, Class AClass C에 주입해줍니다.
    • instance: B 부분에서 볼 수 있듯이, Class BClass AClass C 모두에 주입되어 동일한 인스턴스로 관리됩니다.

Inversion of Control (IoC)의 의미

Inversion of Control(제어의 역전)은 객체의 생성과 의존성 관리를 객체 자신이 아닌 외부 IoC 컨테이너가 담당하도록 하는 개념입니다. Class AClass CClass B가 필요하지만, 스스로 이를 생성하지 않고 IoC 컨테이너에 의해 제공받습니다. 이 방식으로 객체 간의 결합도가 낮아지고, 객체 생성과 관련된 제어 흐름이 외부 컨테이너로 이동합니다.

Dependency Injection (DI)의 적용

  • Dependency Injection(DI)*IoC를 구현하는 방법 중 하나입니다. 위 다이어그램에서는 DI를 통해 Class AClass CClass B의 인스턴스를 주입받고 있습니다. NestJS의 IoC 컨테이너는 이 DI를 통해 Class B의 인스턴스를 생성하고, Class AClass C의 생성자에 주입합니다.

NestJS에서의 IoC와 DI의 장점

  • 결합도 감소: Class AClass CClass B의 구체적인 생성 방법을 몰라도 됩니다. 이를 통해 코드 간 결합도가 낮아지고, 클래스 간의 의존 관계가 유연해집니다.
  • 유연성: Class B의 구현체를 변경하더라도, Class AClass C는 영향을 받지 않습니다. IoC 컨테이너가 의존성을 관리하기 때문에 다른 구현체로 쉽게 대체할 수 있습니다.
  • 테스트 용이성: DI를 사용하여 가짜(mock) 객체를 주입할 수 있어, 단위 테스트 시 실제 Class B 대신 테스트용 객체를 사용하여 독립적으로 테스트할 수 있습니다.

결론

이 다이어그램은 NestJS의 IoC 컨테이너가 의존성 주입을 통해 객체를 관리하는 방식을 보여줍니다. IoC 컨테이너가 Class B를 생성하고, Class AClass C에 자동으로 주입함으로써, 의존성 관리를 외부에서 처리하게 됩니다. 이를 통해 결합도를 낮추고 유연성과 테스트 용이성을 높일 수 있습니다.

'NestJS' 카테고리의 다른 글

NestJS 핫리로드 트러블슈팅  (1) 2024.11.16
NestJS Pipe  (0) 2024.11.15
회원가입로직  (2) 2024.11.14
NestJS 초기 파일들의 의미  (3) 2024.11.04
NodeJS 기술적 소개  (2) 2024.11.02
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유