반응형
Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
Tags
- 주간회고
- Java
- 알고리즘
- mysql
- 회고
- 생각정리
- mongo
- react
- js
- next.js
- WIL
- MongoDB
- Git
- 코테
- 트러블슈팅
- 네트워크
- 생각일기
- mongoose
- 리눅스
- til
- 기록
- 자바스크립트
- javascript
- Grafana
- 피드백
- nest.js
- typescript
- CS
- array
- 생각로그
Archives
- Today
- Total
코딩일상
[nest.js] nest.js 뿌수기 공식 docs 모조리 파헤치기[providers]Constructor-based Injection vs Property-based Injection 본문
카테고리 없음
[nest.js] nest.js 뿌수기 공식 docs 모조리 파헤치기[providers]Constructor-based Injection vs Property-based Injection
solutionMan 2025. 12. 11. 21:37반응형
1)Constructor-based Injection (기본, 권장)으로 하는게 나은경우
// cats.service.ts
@Injectable()
export class CatsService {
constructor(
private readonly catsRepository: CatsRepository,
private readonly logger: LoggerService,
) {}
async findAll(): Promise<Cat[]> {
this.logger.log('Finding all cats');
return this.catsRepository.findAll();
}
}
// cats.controller.ts
@Controller('cats')
export class CatsController {
constructor(
private readonly catsService: CatsService,
private readonly validationService: ValidationService,
) {}
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
2)Property-based Injection 으로 하는게 나은경우
Constructor-based Injection 을 하게 되면
// base.service.ts - 기본 서비스
@Injectable()
export class BaseService {
constructor(
private readonly logger: LoggerService,
private readonly config: ConfigService,
private readonly cache: CacheService,
) {}
protected log(message: string) {
this.logger.log(message);
}
}
// ❌ 문제: 모든 하위 클래스가 super()로 모든 의존성을 전달해야 함
@Injectable()
export class CatsService extends BaseService {
constructor(
private readonly catsRepository: CatsRepository,
// 부모의 의존성도 모두 받아야 함!
logger: LoggerService,
config: ConfigService,
cache: CacheService,
) {
super(logger, config, cache); // 😱 번거로움!
}
async findAll(): Promise<Cat[]> {
this.log('Finding all cats');
return this.catsRepository.findAll();
}
}
// ❌ 더 깊은 상속이면 더 끔찍해짐!
@Injectable()
export class PremiumCatsService extends CatsService {
constructor(
private readonly premiumRepository: PremiumRepository,
// CatsService의 의존성
catsRepository: CatsRepository,
// BaseService의 의존성
logger: LoggerService,
config: ConfigService,
cache: CacheService,
) {
super(catsRepository, logger, config, cache); // 😱😱 악몽!
}
}
Property-based Injection 를 사용하게되면
// base.service.ts
@Injectable()
export class BaseService {
@Inject()
protected readonly logger: LoggerService;
@Inject()
protected readonly config: ConfigService;
@Inject()
protected readonly cache: CacheService;
protected log(message: string) {
this.logger.log(message);
}
protected getConfig(key: string): string {
return this.config.get(key);
}
}
// ✅ 훨씬 깔끔!
@Injectable()
export class CatsService extends BaseService {
constructor(
private readonly catsRepository: CatsRepository,
) {
super(); // super()만 호출하면 됨!
}
async findAll(): Promise<Cat[]> {
this.log('Finding all cats'); // 부모의 logger 사용 가능
const limit = this.getConfig('CATS_LIMIT'); // 부모의 config 사용 가능
return this.catsRepository.findAll();
}
}
// ✅ 더 깊은 상속도 문제없음!
@Injectable()
export class PremiumCatsService extends CatsService {
constructor(
private readonly premiumRepository: PremiumRepository,
) {
super(null); // 자신의 의존성만 관리!
}
async findPremiumCats(): Promise<Cat[]> {
this.log('Finding premium cats'); // BaseService의 logger 사용
return this.premiumRepository.findAll();
}
}반응형
Comments
