[코팩] NestJs Dependency Injection & Inversion of Control (의존성 주입 & 제어의 역전)

Seong Hyeon Kim·2024년 2월 20일
0

NestJs

목록 보기
7/14

1. 일반적인 인스턴스화

class B {

}

class A {
  const b = B()
}


calss B 를 class A 에서 사용한다고 가정할때에 const b 라는 변수를 선언하고 그 안에 class B 를 생성해서 넣어줍니다

이것은 A라는 클래스를 인스턴스화 할때마다 A안에 class B 를 생성한다고 생각하면 됩니다.


2.NestJs 에서의 의존성 주입(Dependency Injection)


class B {
  
}


class A {
  constructor(instance: B)
}

Injection : A 말고 어딘가에서 생성한 B 라는 클래스를 A를 생성할때마다 자동으로 넣어주도록 정의한다(주입해준다)

Dependency : class A 는 생성할때부터 이미 class B의 인스턴스가 필요하기 때문에 의존하고 있다.

즉 역전의 관계라고 생각하면 되는데요, 의존성이 있는 클래스를 바로 주입해주고 시작을 한다. 정도로 생각해야 조금은 이해가 되서 저는 그렇게 생각을 하였습니다.


3.Inversion of Control

Inversion of Control 줄여서 IOC 는 1번에서 설명했던 것처럼 일반적으로 인스턴스 생성후 의존성을 주입하려는 과정을 사용자가 따로 정의내릴 필요 없이 프레임워크인 Nestjs는 IOC Container 가 자동으로 생성해서 관리를 한다. 로 이해하면 쉬울것 같습니다.

대표적인 예로 nestjs 에서 nest g resource 로 새로운 컨트롤러를 생성했을때에 자동으로 서 서비스파일에도 의존성이 주입되어있던것을 생각해주면 됩니다.


4. 코드에서의 예시

src\posts\posts.controller.ts


@Controller('posts')
export class PostsController {
  constructor(private readonly postsService: PostsService) {}
  • 포스트 컨트롤러에서의 이부분이 바로 의존성 주입을 한 부분입니다.
  • 이렇게 의존성 주입이 이뤄질수 있게 한 부분은 module.ts 파일에서 이뤄집니다.
  • 만약 처음부터 이뤄진 의존성말고 추가로 내가 만들고싶다면? => 마찬가지로 module.ts 파일에서 추가를 하면 됩니다.

src\posts\posts.module.ts


import { Module } from '@nestjs/common';
import { PostsService } from './posts.service';
import { PostsController } from './posts.controller';

@Module({
  controllers: [PostsController],
  providers: [PostsService],
})
export class PostsModule {}

Module 안에는 현재 2개의 파라미터값을 받고잇습니다. 각각이 상징하는것은 다음과 같습니다.

controllers : 이 모듈의 컨트롤러로 사용될 곳이 어딘지를 지정해줍니다.

providers: 포스트컨트롤러에서 주입하는 값들을 전부 이곳에서 넣어줍니다. 그리고 PostsService 라는 명칭은 어떤 역할을 하는지에 대한 정의인데요, 데이터를 다루는 로직을 작성하는 클래스를 서비스라고 부른다 정도로 우선 이해해주면 될 것 같습니다.


@Injectable()
export class PostsService {
  getAllPosts() {
    return posts;
  }

서비스 파일 안에서도 프로바이더로 사용하고싶은 클래슨는 우선 모듈파일에서 등록해야되고, 서비스파일안에서도 인젝테이블로 애노테이션(@) 해줘야 합니다.


5. App 모듈과 main.ts 파일

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PostsModule } from './posts/posts.module';

@Module({
  imports: [PostsModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

저희가 만들었던 post 컨트롤러는 생성과 동시에 이미 app 모듈에서 imports: [PostsModule] 라는 부분에 정의되어있는것을 볼 수 있습니다.

main.ts 와 파일이 실행되는 순서들

실제로 main.ts 에서 파일이 실행될때 app 모듈을 불러옵니다 마우스를 클릭해서 앱 모듈로 가보겠습니다.


역시나 아까봤던 app 모듈을 불러오고 app 모듈은 또한 import 해온 postModule 을 불러오는것을 확인할 수 있습니다. 그래서 한번 더 클릭해보면,

마찬가지로 post 모듈로 오게 되고 post 모듈에서는 저희가 작업한 컨트롤러와 프로바이더를 통해서 작업이 이뤄지는 구조입니다.

profile
삽질도 100번 하면 요령이 생긴다. 부족한 건 경험으로 채우는 백엔드 개발자

0개의 댓글