개요
tsyringe
는 TypeScript와 JavaScript에서 의존성 주입(Dependency Injection)을 가능하게 하는 경량 라이브러리입니다. 의존성 주입은 객체 간의 결합도를 낮추고, 테스트 가능성을 높이며, 코드의 유지 보수를 쉽게 하는 데 유용합니다.
1. 의존성 주입의 개념
의존성 주입은 객체가 직접 의존성을 생성하지 않고, 외부에서 제공받는 디자인 패턴입니다. 이를 통해 객체 간의 결합도를 낮추고, 모듈화와 테스트 가능성을 높일 수 있습니다.
2. tsyringe 설치
tsyringe
를 설치하려면 npm 또는 yarn을 사용할 수 있습니다.
npm install tsyringe reflect-metadata
또는
yarn add tsyringe reflect-metadata
reflect-metadata
는 데코레이터를 사용하기 위해 필요합니다.
3. 기본 사용법
1. 설정
TypeScript 설정 파일(tsconfig.json
)에서 experimentalDecorators
와 emitDecoratorMetadata
옵션을 활성화해야 합니다.
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
2. 간단한 예제
먼저, 의존성을 정의하고, 이를 tsyringe
를 통해 주입해 보겠습니다.
import 'reflect-metadata';
import { container, injectable, inject } from 'tsyringe';
@injectable()
class Logger {
log(message: string) {
console.log('Logger:', message);
}
}
@injectable()
class UserService {
constructor(@inject(Logger) private logger: Logger) {}
createUser(name: string) {
this.logger.log(`User ${name} created`);
}
}
// 의존성 주입을 통해 객체 생성
const userService = container.resolve(UserService);
userService.createUser('John Doe');
위 예제에서 Logger
와 UserService
클래스는 @injectable()
데코레이터로 표시되어 tsyringe 컨테이너에 등록됩니다. UserService
의 생성자에서 Logger
를 주입받아 사용합니다. container.resolve(UserService)
를 통해 UserService
인스턴스를 생성할 때, tsyringe가 자동으로 Logger
인스턴스를 주입합니다.
4. 고급 사용법
1. 싱글톤 패턴
tsyringe는 싱글톤 패턴을 쉽게 구현할 수 있습니다.
@singleton()
class DatabaseConnection {
connect() {
console.log('Database connected');
}
}
// 싱글톤 인스턴스 주입
const db1 = container.resolve(DatabaseConnection);
const db2 = container.resolve(DatabaseConnection);
console.log(db1 === db2); // true
2. 등록 방식
tsyringe는 클래스를 자동으로 주입하는 것 외에도 수동으로 주입할 수 있는 다양한 방법을 제공합니다.
interface IDatabase {
connect(): void;
}
@injectable()
class MySQLDatabase implements IDatabase {
connect() {
console.log('MySQL Database connected');
}
}
// 인터페이스와 구현체를 수동으로 등록
container.register<IDatabase>('IDatabase', {
useClass: MySQLDatabase
});
@injectable()
class App {
constructor(@inject('IDatabase') private database: IDatabase) {}
start() {
this.database.connect();
}
}
const app = container.resolve(App);
app.start();
3. Factory와 Value Providers
tsyringe는 팩토리와 값 제공자도 지원합니다.
// 값 제공자
container.register('API_URL', { useValue: 'https://api.example.com' });
@injectable()
class ApiService {
constructor(@inject('API_URL') private apiUrl: string) {}
fetchData() {
console.log(`Fetching data from ${this.apiUrl}`);
}
}
const apiService = container.resolve(ApiService);
apiService.fetchData();
5. 다른 의존성 주입 라이브러리와의 비교
InversifyJS
- 장점: InversifyJS는 더 많은 기능과 유연성을 제공하며, 대규모 애플리케이션에 적합합니다.
- 단점: 설정이 다소 복잡하고, 사용법이 tsyringe보다 어렵습니다.
tsyringe
- 장점: 경량 라이브러리로 설정이 간단하고 사용법이 직관적입니다. 소규모에서 중규모 애플리케이션에 적합합니다.
- 단점: 기능이 InversifyJS보다 제한적입니다.
6. 요약
tsyringe
는 TypeScript와 JavaScript에서 의존성 주입을 쉽게 구현할 수 있는 경량 라이브러리입니다. 이를 통해 코드의 결합도를 낮추고, 테스트 가능성과 유지보수성을 높일 수 있습니다. tsyringe
는 설정이 간단하고 사용법이 직관적이어서, 소규모에서 중규모 애플리케이션에 특히 유용합니다.
주요 포인트:
@injectable
데코레이터로 클래스 등록@inject
데코레이터로 의존성 주입container.resolve
로 인스턴스 생성- 싱글톤, 수동 등록, 값 제공자 등 다양한 기능 지원
reference :