포도가게의 개발일지

Angular DI의 이해 본문

Nest

Angular DI의 이해

grape.store 2022. 9. 22. 23:46
반응형

DI 시스템에는 두가지 역할인 provider와 consumer 역할이 있다.

 

Angular는 injector를 이용하여 provider와 consumer의 interaction을 수월하게 해줍니다.

dependency가 요청되었을때, injector는 registry에서 사용 가능한 instance가 있는지 확인합니다. 그렇지 않은 경우 새 instance가 만들어지고 registry에 저장됩니다. angular는 application bootstrap중에 root injector를 만들뿐만아니라 필요에 따라 다른 injector도 만들게 됩니다.

 

생성자 depedency를 확인하여 injector에 해당 instance가 등록되어있는지 확인 후 없는경우 생성 후 등록해줍니다.

 

DI 프레임워크는 기본적으로 계층적이며, local injector에서 시작하면 root injector 까지 search 해 나간다. 마지막으로 root injector까지 provider가 없으면 DI 프레임워크에서 오류가 발생한다.

 

클래스 인터페이스를 통해 인터페이스를 구현할 수 있습니다. 단 클래스 인터페이스는 consumer가 호출할 수 있는 멤버만 정의해야합니다.

 

single instance는 두개의 a,b 인스턴스가 서로를 참조할 때 문제가 된다. 이로인해 forwardRef()를 통해 angular가 나중에 확인할 수 있는 간접 참조를 만듭니다.

 

  1. 각 데코레이터의 표현은 위에서 아래로 평가(evaluate)됩니다.
  2. 그런 다음 결과는 아래에서 위로 함수로 호출(call)됩니다.

 

백엔드 애플리케이션은 갖추어야 할 요구사항이 많이 있습니다. 여기서 요구사항이라 함은 서비스가 제공하는 핵심 기능을 해결하기 위한 사용자의 요구사항 뿐만 아니라 유효성 검사, 로깅, 보안, 트랜잭션과 같이 애플리케이션 전반에 걸쳐 제공해야 하는 공통 요소를 포함합니다. 이를 횡단관심사라고 부릅니다.

 

소스코드에서 횡단관심사를 따로 분리하여 구현하지 않으면 우리가 작성하는 애플리케이션의 코드는 횡단관심사의 코드와 섞여 뒤죽박죽이 되고 맙니다. 코드는 읽고 이해하기 힘들게 되고 모듈로서 응집도가 떨어질 뿐 아니라 유지보수가 어렵게 됩니다.

 

Nest는 데코레이터를 활용하여 AOP를 적용합니다. Nest에서 AOP를 구현함에 있어 전역으로 적용되지 않고 특정 컴포넌트에만 적용할 때에는 데코레이터를 사용합니다. 이를 잘 활용하면 핵심코드만 짧고 이해하기 쉽게 작성할 수 있습니다.

 

Scope

-  종속성을 가진 컴포넌트의 스코프를 따라가게 됩니다.

  • DEFAULT : 싱글톤 인스턴스가 전체 애플리케이션에서 공유됩니다. 인스턴스 수명은 애플리케이션 수명주기와 같습니다. 애플리케이션이 부트스트랩(각주. 애플리케이션 또는 시스템이 구동되는 것) 과정을 마치면 모든 싱글톤 프로바이더의 인스턴스가 만들어집니다. 따로 선언하지 않으면 DEFAULT가 적용됩니다.
  • REQUEST : 들어오는 요청마다 별도의 인스턴스가 생성됩니다. 요청을 처리하고 나면 인스턴스는 쓰레기 수집(garbage-collected)됩니다.
  • TRANSIENT : 이 스코프를 지정한 인스턴스는 공유되지 않습니다. 임시(TRANSIENT) 프로바이더를 주입하는 각 컴포넌트는 새로 생성된 전용 인스턴스를 주입받게됩니다.

 

매우 작은 애플리케이션이라면 하나의 모듈만 있어도 충분하겠지만 응집도를 높이는 작업을 게을리 하면 의존관계가 복잡한 코드로 변하는 것은 시간 문제입니다.

 

AppModule은 앱을 구동시키기 위해 CoreModule이 필요한데 CommonModule의 기능도 필요합니다. 이런 경우 AppModule은 둘 다를 가져오는 것이 아니라 CoreModule만을 가져오고, CoreModule에서는 가져온 CommonModule을 다시 내보내면 AppModule에서 CommonModule을 가져오지 않아도 사용할 수 있습니다.

 

export class UsersController {
  constructor(private readonly usersService: UsersService) { }
    ...
}

UsersController는 UsersService에 의존하고 있습니다. 하지만 UsersService 객체의 라이프 사이클에는 전혀 관여하지 않습니다. 어디선가 자신의 생성자에 주어지는 객체를 가져다 쓰고 있을 뿐입니다. 이 역할을 하는 것이 IoC입니다.

 

웹 개발에서 일반적으로 미들웨어라 함은 라우트 핸들러가 클라이언트의 요청을 처리하기 전에 수행되는 컴포넌트를 말합니다.

 

어디선가 알고 있어야 하는 정보, 이를 메타데이터1라고 합니다. "create 메서드는 admin 역할일 때만 호출되어야 한다"고 하는 메타데이터를 @SetMetadata() 데코레이터로 지정할 수 있습니다.

 

Nest는 메타데이터를 다루기 위한 헬퍼 클래스로 Reflector 클래스를 제공합니다. Reflector를 이용하여 메타데이터 읽고 저장된 값과 비교해 보도록 합시다.

 

 예를 들어 사용자가 어떤 유료 서비스를 구독하고 있고 매달 결제가 일어난다고 했을 때 매일 특정 시간에 결제일이 도래한 고객의 신용카드 결제가 일어나도록 해야 합니다. 이런 주기적 반복 작업을 태스크(Task) 또는 배치(batch, 일괄처리)라고 부릅니다. 

 

common_1.Injectable을 호출하여
함수에 Reflect.defineMetadata 함수를 return 시켜 고차함수를 어레이에 주입

추후 등록할 key 설정을 안해주었기 때문에 generateDecorator를 호출하여 metadataMap에 등록함

해당 class가 어떤 metadata를 가지고있는지 들고있는 map

 

'Nest' 카테고리의 다른 글

[Nest] 정리  (0) 2022.03.27
Comments