의존성 주입과 제어의 역전

클래스 A와 클래스 B가 있을 때, B를 외부에 만들어 두고, A에서 constructor로 B를 받는다.

class A {
  constructor(instance: B)
}

class B {}

class C {
  constructor(instance: C)
}
  • 클래스 A를 사용할 때, 클래스 B가 필요하기 때문에, A는 B에 의존하게 된다.

  • B를 주입해줘야 하는것이다.
    - 그렇기 때문에 Dependency injection 이라고 한다.

  • 클래스 A, 클래스 C클래스 B를 만들어 주입 받아야 하는데, 인스턴스를 생성하고, 삭제하고 주입하는 과정을 프레임워크가 직접 담당한다.
    - Inversion of Control 제어의 역전이라고 한다.
    - 프레임워크가 인스턴스를 생성하고 주입, 삭제를 하는 과정을 담당함으로써, 개발자는 인스턴스의 라이프 사이클에 신경쓰지 않아도 된다.

Modules

@Controller('posts')

export class PostsController {

  constructor(private readonly postsService: PostsService) {}
	...
}

Controller에서 보면 PostsService를 인스턴스를 생성하지 않고, constructor에 작성만 하는데도 PostService에 있는 메서드들을 가져와 사용할 수 있다.

  • NestJs의 IoC 컨테이너가 주입되어야 하는 서비스들을 생성해준다.
  • <service name>.modules.ts에 작성하면 IoC 컨테이너로 관리할 수 있다.
import { Module } from "@nestjs/common"
import { PostsService } from "./posts.service"
import { PostsController } from "./posts.controller"

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

@Module 애너테이션이있는 module 파일에 보면 controllersproviders가 있다.

  • 인스턴스를 작성해서 넣은것이 아닌, 클래스를 넣었다.
  • 이 모듈이 생성되면서 클래스를 인스턴스화를 하고싶은게 아닌 IoC 컨테이너가 자동으로 인스턴스화 하고 관리하게 하기위함.
    - 어떤 클래스를 관리해야하는 것인지 알려주는 개념이다.
  • providers 안에는 PostsService가 아니더라도, 인스턴스를 관리해주길 바라는 다른 기능들을 추가로 넣어줄 수 있다.
    - 이 모듈 안에서 있는 providers 안에 있는 클래스들은 인스턴스화를 하여 constructor에 주입받아 사용할 수 있게되는 것이다.
@Injectable()

export class PostsService {
...
}

또한 provider에 작성하고, providers에 입력하기 위해서는 @Injectable() 애너테이션을 추가한다.

AppModule

module은 결국 작성된 controller와 인스턴스 관리될 providers에 있는 객체만 관리하는 개념이다.

  • module을 관리하는 module이 또 존재한다.
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 {}

AppModule을 보면 imports 라는 항목이 존재한다. 그리고 그 항목 안에는 PostsModule이 클래스로 들어가있다.

  • NestJs를 처음 생성하면 생성되는 AppModule이 바로 module을 관리하는 module인 것이다.

main.ts

import { NestFactory } from "@nestjs/core"
import { AppModule } from "./app.module"

async function bootstrap() {
  const app = await NestFactory.create(AppModule)
  await app.listen(3000)
}

bootstrap()

yarn start 혹은 npm start를 해서 서버를 실행시키고, 리눅스에서 프로세스를 보게되면 NestJs를 시작하는 프로세스가 가리키는 곳이 main.ts이다.

  • NestFactory 라는 클래스가. create() 메서드를 호출하는데 그 안에 파라미터로 AppModule을 받고있다.
  • 서버가 실행되는 첫 부분에서, 작성된 명령들이 어디에 어떻게 관리되어있는데 명부를 작성한것과 같은 개념이다.
  • AppModule을 명시해놓았기 때문에, 서버는 AppModule에 적힌 다른 모듈들을 보고 인스턴스를 관리하는 개념으로 뻗어나간다 생각하면 된다.

    모든 내용은 강의 [코드팩토리][초급] NestJS REST API 백엔드 완전 정복 마스터 클래스를 수강하며 정리하는 내용들을 올린 글이다.

profile
자유로운 개발자

0개의 댓글