๐ NestJS ModuleRef – ๋์ ๋ชจ๋ ์ธ์คํด์ค ์ฃผ์ ์์ ๊ฐ์ด๋
๐ NestJS ModuleRef – ๋์ ๋ชจ๋ ์ธ์คํด์ค ์ฃผ์ ์์ ๊ฐ์ด๋
NestJS์์ ModuleRef๋ ๋์ ์ผ๋ก ๋ชจ๋ ์ธ์คํด์ค๋ฅผ ์ฃผ์
ํ ์ ์๋๋ก ๋์์ฃผ๋ ๋๊ตฌ์
๋๋ค.
์ด๋ฒ ๊ธ์ NestJS ๊ณต์ ๋ฌธ์ ModuleRef๋ฅผ ๊ธฐ๋ฐ์ผ๋ก,
์ค๋ฌด์์ ModuleRef๋ฅผ ํ์ฉํ์ฌ ๋์ ์ฃผ์
๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช
ํฉ๋๋ค.
๐ก "ํน์ ์ํฉ์์๋ง ํ์ํ ์๋น์ค๋ฅผ ๋์ ์ผ๋ก ์ฃผ์ ํ์ฌ, ๋ฉ๋ชจ๋ฆฌ์ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค."
โ ModuleRef๋?
- NestJS์ ๋ชจ๋ ์ธ์คํด์ค๋ฅผ ๋์ ์ผ๋ก ๊ฐ์ ธ์ค๊ธฐ ์ํด ์ฌ์ฉํ๋ ํด๋์ค์ ๋๋ค.
- ์ํ ์์กด์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ฑฐ๋, ๋ฐํ์์ ํน์ ์๋น์ค๋ฅผ ์ฃผ์ ํ ๋ ์ฌ์ฉํฉ๋๋ค.
๐ฆ ์ค์น
ModuleRef๋ NestJS์ ๊ธฐ๋ณธ ๋ชจ๋๋ก ํฌํจ๋์ด ์์ด ๋ณ๋์ ์ค์น๊ฐ ํ์ํ์ง ์์ต๋๋ค.
1๏ธโฃ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ – get() ๋ฉ์๋
import { Injectable, ModuleRef } from '@nestjs/core';
@Injectable()
export class DynamicService {
constructor(private moduleRef: ModuleRef) {}
getService(serviceName: string) {
return this.moduleRef.get(serviceName, { strict: false });
}
}
์ฌ์ฉ ์์
const catsService = this.getService(CatsService);
catsService.getCats();
- ๋์ ์ผ๋ก ์๋น์ค ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ด
- strict: false ์ต์ ์ ํตํด ๋ชจ๋ ๊ฒฝ๋ก๊ฐ ๋ช ์์ ์ด์ง ์์๋ ์ฃผ์ ๊ฐ๋ฅ
ModuleRef๋ฅผ ์ฌ์ฉํ์ฌ ๋์ ์ฃผ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์ด ์ง์ ์
๋ธ๋ก๊ทธ ๋ ์๋ค์ด ์ฃผ๋ชฉํ๋ ํต์ฌ ๊ตฌ๊ฐ์ ๋๋ค.
์ ๋์ผ์ค ๊ด๊ณ ๋ฅผ ์ฝ์ ํ๋ฉด CTR์ด ๋๊ฒ ๋์ค๋ ๊ตฌ๊ฐ์ ๋๋ค.
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-XXXXXX"
data-ad-slot="YYYYYY"
data-ad-format="auto"
data-full-width-responsive="true"></ins>
2๏ธโฃ ์ํ ์์กด์ฑ ๋ฌธ์ ํด๊ฒฐ
โ Circular Dependency ํด๊ฒฐ ์ฝ๋
@Injectable()
export class CatsService {
private dogsService: DogsService;
constructor(private moduleRef: ModuleRef) {}
onModuleInit() {
this.dogsService = this.moduleRef.get(DogsService, { strict: false });
}
getRelatedDogs() {
return this.dogsService.getDogs();
}
}
- onModuleInit() ํ์ ๋ชจ๋ ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์์ผ ์ํ ์์กด์ฑ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
3๏ธโฃ Transient Scope์์ ์ฌ์ฉ
- Transient Scope์์๋ DI๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ฃผ์ ๋์ง ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
- ์ด๋ด ๋ ModuleRef๋ฅผ ์ฌ์ฉํ๋ฉด ๋์ ์ผ๋ก ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
โ Transient Service ์์ฑ
@Injectable({ scope: Scope.TRANSIENT })
export class TransientService {
sayHello() {
return 'Hello from Transient Service!';
}
}
โ ๋์ ํธ์ถ
@Injectable()
export class MainService {
constructor(private moduleRef: ModuleRef) {}
async handle() {
const transientService = await this.moduleRef.resolve(TransientService);
console.log(transientService.sayHello());
}
}
**moduleRef.resolve()**๋ ๋งค๋ฒ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ฐํํ์ฌ Transient Scope ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค.
4๏ธโฃ Lazy Loading์ ํตํ ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ
- ํน์ ์๋น์ค๊ฐ ํญ์ ์ฌ์ฉ๋์ง ์๋๋ค๋ฉด ์ด๊ธฐํํ์ง ์๊ณ , ํ์ํ ๋ ๋ก๋ํ๋ ๊ฒ์ด ์ ๋ฆฌํฉ๋๋ค.
โ Lazy Loading ์ฝ๋
@Injectable()
export class LazyService {
constructor(private moduleRef: ModuleRef) {}
private async getDynamicService(): Promise<DynamicService> {
return this.moduleRef.resolve(DynamicService);
}
async executeTask() {
const service = await this.getDynamicService();
return service.runTask();
}
}
๐ง ์ค๋ฌด ํ์ฉ ์ ๋ต
์ํฉ ํด๊ฒฐ ๋ฐฉ๋ฒ
์ํ ์์กด์ฑ ๋ฐ์ | ModuleRef๋ก ๋์ ์ฃผ์ |
Transient Scope ๋ฌธ์ | moduleRef.resolve()๋ก ์๋ก์ด ์ธ์คํด์ค ์ฌ์ฉ |
๋ฐํ์์ ์๋น์ค ์ ํ ํ์ | moduleRef.get()๋ก ์กฐ๊ฑด๋ถ ์ธ์คํด์ค ์ฃผ์ |
๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ์ต์ ํ | Lazy Loading ๊ธฐ๋ฒ ์ ์ฉ |
๐ง ์ฃผ์์ฌํญ
- Singleton ๋ชจ๋์์ Transient ๋ชจ๋ ์ฃผ์
์ ๋งค๋ฒ ๋์ผ ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค.
→ ์ด ๊ฒฝ์ฐ moduleRef.resolve()๋ฅผ ์ฌ์ฉํ์ฌ ํญ์ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ฐ์์ผ ํฉ๋๋ค. - strict: false ์ฌ์ฉ ์, ์๋ชป๋ ๋ชจ๋์ ๊ฐ์ ธ์ฌ ์ํ์ด ์์ต๋๋ค.
→ ๊ตฌ์กฐ๋ฅผ ๋ช ํํ ํ๊ณ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฐ๋์งํฉ๋๋ค.
๐ ๋ง๋ฌด๋ฆฌ ์์ฝ
๊ธฐ๋ฅ ์ค๋ช
get() | ๋ชจ๋ ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ด (๊ธฐ๋ณธ์ ์ผ๋ก Singleton) |
resolve() | ํญ์ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ด (Transient ์ง์) |
Circular Dependency ํด๊ฒฐ | onModuleInit() ํ์ ๋ชจ๋ ์ธ์คํด์ค ํ ๋น |
Lazy Loading | ํ์ํ ์์ ์ ๋ชจ๋์ ๊ฐ์ ธ์ ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ |
NestJS ModuleRef,NestJS Circular Dependency,NestJS Transient Scope ํด๊ฒฐ,NestJS ๋์ ์ฃผ์ ,NestJS Lazy Loading,NestJS Module ์ธ์คํด์ค,NestJS DI ์ต์ ํ,NestJS resolve ์ฌ์ฉ๋ฒ,NestJS ๋ชจ๋ ๊ด๋ฆฌ,NestJS ์ค๋ฌด ํจํด