fontcolor_theme
Deepkit Injector

시작하기

Deepkit의 Dependency Injection은 Runtime Types에 기반하므로, Runtime Types가 이미 올바르게 설치되어 있어야 합니다. 런타임 타입을 참고하세요.

이 작업이 완료되면, @deepkit/injector를 설치하거나, 이미 해당 라이브러리를 내부적으로 사용하는 Deepkit 프레임워크를 사용할 수 있습니다.

npm install @deepkit/injector

라이브러리가 설치되면, 해당 API를 바로 사용할 수 있습니다.

사용법

Dependency Injection을 사용하는 방법은 세 가지가 있습니다.

  • Injector API (저수준)
  • Module API
  • App API (Deepkit 프레임워크)

Deepkit 프레임워크 없이 @deepkit/injector를 사용하려면, 앞의 두 가지 방식을 권장합니다.

Injector API

Injector API는 Dependency Injection 소개에서 이미 다루었습니다. 단일 Class InjectorContext로 하나의 DI 컨테이너를 생성하는 매우 간단한 사용 방식이 특징이며, 모듈이 없는 더 단순한 애플리케이션에 특히 적합합니다.

import { InjectorContext } from '@deepkit/injector';

const injector = InjectorContext.forProviders([
    UserRepository,
    HttpClient,
]);

const repository = injector.get(UserRepository);

이 경우의 injector 객체는 Dependency Injection 컨테이너입니다. InjectorContext.forProviders Function은 Provider 배열을 받습니다. 어떤 값을 전달할 수 있는지는 Dependency Injection Providers 섹션을 참고하세요.

Module API

더 복잡한 API로 InjectorModule Class가 있으며, Provider들을 서로 다른 모듈에 저장하여 모듈별로 캡슐화된 DI 컨테이너를 여러 개 만들 수 있습니다. 또한 모듈별로 configuration Class를 사용할 수 있어, 자동으로 검증된 configuration 값을 Provider에 쉽게 제공할 수 있습니다. 모듈들은 서로를 import하고, Provider를 export하여 계층을 구축하고 깔끔하게 분리된 아키텍처를 만들 수 있습니다.

애플리케이션이 더 복잡하고 Deepkit 프레임워크를 사용하지 않는 경우 이 API를 사용하는 것이 좋습니다.

import { InjectorModule, InjectorContext } from '@deepkit/injector';

const lowLevelModule = new InjectorModule([HttpClient])
     .addExport(HttpClient);

const rootModule = new InjectorModule([UserRepository])
     .addImport(lowLevelModule);

const injector = new InjectorContext(rootModule);

이 경우의 injector 객체는 Dependency Injection 컨테이너입니다. Provider는 여러 모듈로 나눌 수 있고, 모듈 import를 통해 다양한 위치에서 다시 가져올 수 있습니다. 이는 애플리케이션 또는 아키텍처의 계층을 반영하는 자연스러운 계층 구조를 만듭니다. InjectorContext에는 항상 계층의 최상위 모듈(루트 모듈 또는 앱 모듈)을 전달해야 합니다. 이후 InjectorContext는 중개 역할만 하며, injector.get() 호출은 단순히 루트 모듈로 전달됩니다. 다만, 두 번째 인자로 모듈을 전달하면 루트가 아닌 모듈의 Provider도 가져올 수 있습니다.

const repository = injector.get(UserRepository);

const httpClient = injector.get(HttpClient, lowLevelModule);

루트가 아닌 모든 모듈은 기본적으로 캡슐화되어, 해당 모듈의 모든 Provider는 그 모듈 내부에서만 사용할 수 있습니다. 다른 모듈에서도 사용하려면 해당 Provider를 export해야 합니다. export하면 Provider는 계층의 상위 모듈로 이동하며, 그 방식으로 사용할 수 있습니다.

모든 Provider를 기본적으로 최상위인 루트 모듈로 export하려면 forRoot 옵션을 사용할 수 있습니다. 이렇게 하면 모든 Provider를 다른 모든 모듈에서 사용할 수 있습니다.

const lowLevelModule = new InjectorModule([HttpClient])
     .forRoot(); //모든 Provider를 루트로 export

App API

Deepkit 프레임워크를 사용하면, 모듈은 @deepkit/app API로 정의합니다. 이는 Module API를 기반으로 하므로, 그 기능을 그대로 사용할 수 있습니다. 추가로 강력한 hook을 사용하고 configuration loader를 정의하여 더욱 동적인 아키텍처를 구성할 수 있습니다.

프레임워크 모듈 장에서 더 자세히 설명합니다.

import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { HttpRouterRegistry, HttpBody } from '@deepkit/http';

interface User {
    username: string;
}

class Service {
    users: User[] = [];
}

const app = new App({
    providers: [Service],
    imports: [new FrameworkModule()],
});

const router = app.get(HttpRouterRegistry);

router.post('/users', (body: HttpBody<User>, service: Service) => {
    service.users.push(body);
});

router.get('/users', (service: Service): Users => {
    return service.users;
});
English中文 (Chinese)한국어 (Korean)日本語 (Japanese)Deutsch (German)