NestJs DI (Dependency Injection)

M·2023년 8월 10일
0

TIL

목록 보기
30/42

dependencies?

dependencies는 클래스가 동작하기 위해 필요한 서비스나 객체를 의미한다.

dependency InJection?

dependency InJection(DI)는 class가 의존성 객체를 외부에 요청하고,
외부에서 인스턴스를 생성해서 주입한다.

DI의 장점

  1. 코드간의 의존성을 줄여준다.
  2. 재사용성이 높아진다.
  3. 가독성이 높아진다.

@Injectable()

외부에서 생성자를 통해 의존성 주입을 하기 위해서는
의존성 주입의 대상을 지정해 줘야한다.
NestJs에서는 injectable 데코레이터를 붙여주면 주입 대상이 된다.
위에 말했다시피 @Injectable() 데코레이터로 지정을 해야 가능하다.
ex

// projects.service.ts
@Injectable()
export class ProjectService {
    constructor(
      @InjectRepository(Project)
      private projectRepository: Repository<Project>,
    ) {};

    async getProject(projectId: number, userId: number): Promise<Object> {
    const existProject = await this.projectRepository.findOne({ where: { id: projectId } });
    if (!existProject) throw new HttpException('해당 프로젝트를 찾을 수 없습니다.', HttpStatus.NOT_FOUND);

    const existAuthorization = await this.projectMemberRepository.findOne({
      where: { project: { id: projectId }, user: { id: userId }, participation: true },
    });
    if (!existAuthorization) throw new HttpException('해당 프로젝트의 조회 권한이 없습니다.', HttpStatus.UNAUTHORIZED);

    const project = await this.projectRepository.findOne({ where: { id: projectId } });
    return project;
  }
  
}

commentsService에서 projectService를 DI

일단 나는 comments.service.ts에서 project 조회를 위해 projectService를 DI했다.

// project.module.ts
import { Module } from '@nestjs/common';
import { ProjectsController } from './projects.controller';
import { ProjectsService } from './projects.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Project } from 'src/_common/entities/project.entity';
import { ProjectMember } from 'src/_common/entities/projectMember.entity';
import { JwtService } from 'src/jwt/jwt.service';
import { AccessAuthGuard } from 'src/_common/security/access.auth.guard';
import { UsersService } from 'src/users/users.service';
import { User } from 'src/_common/entities/user.entity';
import { MailService } from 'src/mail/mail.service';

@Module({
  imports: [TypeOrmModule.forFeature([Project, ProjectMember, User])],
  controllers: [ProjectsController],
  providers: [ProjectsService, JwtService, AccessAuthGuard, UsersService, MailService],
  exports: [ProjectsService], // <- 외부로 내보냄 
})
export class ProjectsModule {}

exports를 사용해서 ProjectsService를 외부로 내보내고

// comments.module.ts
import { Module } from '@nestjs/common';
import { CommentsController } from './comments.controller';
import { CommentsService } from './comments.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Comment } from '../_common/entities/comment.entity';

import { ProjectsModule } from '../projects/projects.module';
import { BoardsModule } from '../boards/boards.module';

import { JwtService } from 'src/jwt/jwt.service';
import { AccessAuthGuard } from 'src/_common/security/access.auth.guard';
import { UsersService } from 'src/users/users.service';
import { User } from 'src/_common/entities/user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Comment, User]), ProjectsModule, BoardsModule], // <- ProjectsModule을 imports
  controllers: [CommentsController],
  providers: [CommentsService, JwtService, AccessAuthGuard, UsersService],
})
export class CommentsModule {}

imports를 사용해서 ProjectsModule을 가져온뒤

// commets.service.ts
import { BadRequestException, HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Comment } from 'src/_common/entities/comment.entity';
import { ProjectsService } from '../projects/projects.service'; // <- ProjectService import
import { BoardsService } from '../boards/boards.service';

@Injectable()
export class CommentsService {
  constructor(
    @InjectRepository(Comment)
    private commentRepository: Repository<Comment>,
    private projectsService: ProjectsService, // <- 생성자를 통해 DI
    private boardsService: BoardsService,
  ) {}

  // 댓글 생성
  async createComment(content: string, id: number, projectId: number, boardId: number, replyId: string): Promise<string> {
    // 데이터 유효성 검증
    if (!content) {
      throw new BadRequestException('댓글을 입력해주세요.');
    }
    // 해당 프로젝트가 존재하고, 프로젝트 참여 인원인지 검증
    const existProject = await this.projectsService.getProject(projectId, id); // <- projectsService내에 있는 getProject메서드 사용 
    if (!existProject) {
      return;
    }
    // 해당 프로젝트에 보드가 존재하는지 검증
    const existBoard = await this.boardsService.getBoard(boardId);
    if (!existBoard) {
      return;
    }
}

이로인해 CommentsService에서 ProjectsService에 있는 메서드를 사용할 수 있다.
갈 길이 멀어 보이지만 꾸준히 파다보면 뭐라도 얻을테니.. 더 열심히 해야겠다.

이 글을 보고 틀린 사실이 있다면, 댓글 달아주시면 감사하겠습니다.

profile
자바스크립트부터 공부하는 사람

1개의 댓글

comment-user-thumbnail
2023년 8월 10일

좋은 정보 감사합니다

답글 달기