useClass와 useExisting의 비교 - different between useClass and useExisting
이번 시간은 module에서 providers를 설정 시 useClass와 useExisting 의 차이를 알아보겠습니다.
useClass
Injectable class의 이름을 변경하여 사용할 수 있습니다.
이 때, 이름은 반드시 존재하는 다른 Injectable class의 명이여야 합니다.
사용법은 다음과 같습니다.
providers: [
{ provide: ProductService, useClass: fakeProductService }
]
useExisting
기존 토큰을 참조하되 별칭을 지정합니다.
반드시 두 injectable class가 존재해야 합니다.
providers: [
NewProductService,
{ provide: ProductService, useExisting: NewProductService },
];
different between useClass and useExisting
얼핏 보면 useClass와 useExisting은 유사해 보이는데 왜 다른 옵션을 제공하고 있을까요?
이 두 차이를 예제를 통해 자세히 알아봅시다.
Setting Default Services for Testing
예를 들어 두 가지 service가 존재한다고 합시다. 두 service는 형태는 유사하지만 값이 다른 모양으로 쉽게 구분할 수 있게 구성하였습니다.
@Injectable()
export class TestService {
index = 0;
add(): number {
return ++this.index;
}
}
@Injectable()
export class NewTestService {
index = 0;
add(): number {
this.index += 10;
return this.index;
}
}
component에서 두 service를 매 초 호출한다고 가정합시다.
export class AppComponent {
constructor(
private testService: TestService,
private newTestService: NewTestService
} {
setInterval(() => {
console.log('test', this.testService.add());
console.log('newTest', this.newTestService.add());
}, 1000)
}
그리고 각각의 모듈의 다른 설정의 예제를 통해 왜 이런 기능을 구분하게 되었는지 알아보겠습니다.
기본 provider 설정
일반적인 방법으로 providers에 service를 직접 설정해보고 결과를 확인해봅시다.
// app.module
...
providers: [
TestService,
NewTestService
]
결과는 예상과 같이 두 service가 각각 다르게 동작함을 확인할 수 있습니다.
// result
test: 1
newTest: 10
test: 2
newTest: 20
test: 3
newTest: 30
test: 4
newTest: 40
useClass 활용
useClass를 활용하여 TestService를 NewTestClassService로 명명해봅시다.
// app.module
providers: [
TestService,
{provide: NewTestService, useClass: TestService },
]
결과는 NewTestService가 TestService로 전환되었으며, 기존 TestService와는 다른 Service인 것처럼 각각 다르게 동작함을 확인할 수 있습니다.
// result
test: 1
newTest: 1
test: 2
newTest: 2
test: 3
newTest: 3
test: 4
newTest: 4
useExisting 활용
위의 useClass와 동일한 조건에서 useClass만 useExisting으로 변경해보고 결과를 확인해봅시다.
// module
providers: [
TestService,
{provide: NewTestService, useExisting: TestService },
]
결과는 NewTestService가 TestService로 전환되었으며, 기존 TestService와 마치 하나의 Service인 것처럼 데이터를 공유하고 있음을 확인할 수 있습니다.
// result
test: 1
newTest: 2
test: 3
newTest: 4
test: 5
newTest: 6
test: 7
newTest: 8
Angular Standalone에서 useClass와 useExisting 활용
standalone에서는 module을 사용하지 않으므로 위의 예제를 활용하려면 service에서 직접 선언해야 합니다.
Injectable의 파라미터에서 useClass와 useExisting을 제공하므로 이를 활용할 수 있습니다.
위의 예제를 수정해봅시다.
useClass
@Injectable({
providedIn: 'root',
useClass: TestService
})
export class NewTestService {
index = 0;
add(): number {
this.index += 10;
return this.index;
}
}
useExisting
@Injectable({
providedIn: 'root',
useExisting: TestService
})
export class NewTestService {
index = 0;
add(): number {
this.index += 10;
return this.index;
}
}
댓글남기기