작성
·
428
·
수정됨
0
진작에 질문을 남겼어야 했는데, 애러 해결이 어려워 너무 지체되네요. 첫 질문 남기게 되었습니다.
문제의 요지
: 추측 하기로container.resolve
가 vue 와 라이프사이클 에 순서때문인지, 다른 이유가 있는지 DI 가 안됩니다.
강의내용에도 있듯 tsyringe 는@singleton
이 달려있는
클래스를 컨테이너에 등록 후, 클래스 자체를 DI 키로 사용할 수 있다고 알고있습니다. 디버깅 상황에서 보다시피container
내부 _registryMap
안에 AuthorityApi
클래스가 정상등록 된 것을 확인할 수 있었습니다.
하지만 Break-point 된 container.resolve
처리가 안되어 아래처럼 애러가 발생합니다. 아래는 다음줄로 가지않고, 이벨류에이터로 실행한 모습이구요, AuthorityApi
를 찾아올 수 없다 합니다.
Error: TypeInfo not known for "AuthorityApi"
at http://localhost:4000/node_modules/.vite/deps/tsyringe.js?v=a355aabe:746:17
at InternalDependencyContainer2.construct (http://localhost:4000/node_modules/.vite/deps/tsyringe.js?v=a355aabe:751:6)
at InternalDependencyContainer2.resolveRegistration (http://localhost:4000/node_modules/.vite/deps/tsyringe.js?v=a355aabe:573:90)
at InternalDependencyContainer2.resolve (http://localhost:4000/node_modules/.vite/deps/tsyringe.js?v=a355aabe:500:25)
at eval (eval at setup (http://localhost:4000/src/widgets/Menu.vue:28:26), <anonymous>:1:11)
at setup (http://localhost:4000/src/widgets/Menu.vue:28:26)
at callWithErrorHandling (http://localhost:4000/node_modules/.vite/deps/chunk-VJROVW5H.js?v=a355aabe:1884:19)
at setupStatefulComponent (http://localhost:4000/node_modules/.vite/deps/chunk-VJROVW5H.js?v=a355aabe:8253:25)
at setupComponent (http://localhost:4000/node_modules/.vite/deps/chunk-VJROVW5H.js?v=a355aabe:8214:36)
at mountComponent (http://localhost:4000/node_modules/.vite/deps/chunk-VJROVW5H.js?v=a355aabe:5604:7)
해결방법을 tsyringe 공식 깃헙이슈, 구글링, 스택오버플로 몽창 뒤져봐도 힌트얻기가 참으로 힘드네요. AI 센세는 그저 스택오버플로 내용만 읊어줍니다.
이것에 원인을 알 수 있을까요? 실마리만 얻어도 해결하기 수월할텐데, 몇일 째 어째야 되나 고민입니다. 도움을 얻을 수 있을까요?
주의: 개인 npm lib 가 포함되어 node_modules
을 포함한 체 그대로 압축된 파일입니다. npm i
인스톨 없이 앱을 실행해야될거라 예상합니다.
도움을 구합니다. 감사드려요.
답변 2
0
⚠ 기존 댓글에 정리된 내용이 적절치 않아 삭제 후, 실제 동작하는 방법에 대해 다시 정리합니다.
다음은 알려진 OOP 인터페이스 분리 패턴(ISP)을 TS기반
tsyringe
에서 추상클래스를 InjectionToken 으로 사용하는 방법입니다.
updates:
24-09-19: InjectionToken 형 변환 시, as InjectionToken
에서 `as InjectionToken
또는 as unknown as InjectionToken
으로 변경
: 추상클래스를 상속,확장합니다.
abstract class Super {}
class Impl extends Super {}
@registry([..])
추가@singleton()
// ✅ @registry 에 직접 연관된 부모클래스(추상체)를 지정해야 @inject 를 통해 주입이 가능해집니다.
@registry([
{
// 💡 tsyringe 는 추상클래스 등록을 지원하지 않아 타입미스매치 애러 발생.
// 해결은 unknown as InjectionToken 으로 강제 케스팅 후 등록이 가능함.
// 1안
token: Super as InjectionToken,
// 또는 2안
token: Super as unknown as InjectionToken,
useClass: Impl,
},
])
class Impl extends Super {}
export class ConstructorInjectionWithTsyringe {
constructor(
@inject(Impl)
readonly sup: Super,
) {}
}
아래는 질문의 소스코드 디버깅 상황에서 캡쳐된 이미지입니다. 추상클래스 HttpClient
타입 맴버변수에, 구현체 AxiosHttpClient
인스턴스가 정상 주입된 것을 확인할 수 있었습니다.
0
import {AxiosHttpClient, HttpClient, type ResponseHandlerOptions} from '@/features'
@singleton()
export class AuthorityApi {
constructor(@inject(HttpClient) readonly httpClient: AxiosHttpClient) {}
// 생략
}
AuthorityApi의 생성자 주입이 안되는 상태입니다.
때문에 외부에서 container.resolve(AuthorityApi)가 안먹히는 상황입니다.
위 코드와 같이 AxiosHttpClient를 직접 지정해서 해결할 수 있습니다.
혹은 tsyringe 예제 문서와 같이 interface를 이용해서 주입할수도 있긴합니다.
관련링크: https://github.com/microsoft/tsyringe?tab=readme-ov-file#example-with-interfaces
일반적인 OOP 방식처럼, inject 데코레이터에 구현체클래스, 필드변수타입에 추상체클래스 선언이 가능한 방법이 있었습니다. 너무 해맨것 치고 너무 해결방법이 간단해 허탈했고, 알려주신 방법이 다른 경우에서 잘 안되는거 같아, 용법을 새-댓글에 다시 정리하게 되었어요.
:: 추가이슈 해결 ::
문제
: 추상클래스를
container.resolve
인수로 대입 시, 반환된 인스턴스가any
타입으로 추론됩니다.: AppLogger 가 추상클래스 일때, InjectionToken 으로 형변환 시, 변수
log
는any
타입으로 추론됩니다. 이로인해 IDE 의 메서드 추론기능을 사용할 수 없습니다.해결:
InjectionToken
타입의 구성은 다음과 같습니다.이 중에
constructor<T>
를 사용해서 강제케스팅 합니다.적용코드: