---
id: adr-0006-manual-di-interface-services
title: "ADR-0006 수동 의존성주입과 인터페이스 서비스"
category: "Architecture_Decision"
status: "draft"
verification_status: "applied"
canonical_id: ""
aliases: ["ADR DI", "왜 DI 컨테이너 안 쓰나", "수동 주입 결정", "인터페이스 서비스 결정"]
duplicate_of: ""
source_trust_level: "A"
confidence_score: 0.89
created_at: 2026-06-13
updated_at: 2026-06-13
review_reason: ""
merge_history: []
tags: ["adr", "dependency-injection", "decision", "architecture", "astraai"]
raw_sources: ["AstraAI/src/extension.ts", "AstraAI/src/core/services.ts", "AstraAI/src/intelligence/criticAgent.ts"]
applied_in: ["AstraAI"]
github_commit: ""
---

# [[ADR-0006 수동 의존성주입과 인터페이스 서비스]]

## 🎯 한 줄 통찰 (One-line insight)
의존성 주입을 **DI 프레임워크 없이 entry point(`activate`)에서 손으로 조립**하고, 외부 효과를 가진 협력자는 **인터페이스/함수 타입으로 추상화**해 주입하기로 결정했다 — 조립 지점이 하나뿐이라 컨테이너의 비용이 불필요하기 때문 [S1][S2].

## 🧠 핵심 개념 (Core concepts)
- **결정:** 수동 생성자/함수/getter 주입 + IAIService/IBrainService/CritiqueLlmCall 추상화.
- 구현 상세는 [[의존성 주입과 서비스 인터페이스]] 참조.

## 📖 세부 내용 (Details · ADR)
### Problem
협력자(AI 서비스, 스트리머, 큐, LLM 호출)를 객체가 직접 생성하면 결합이 강해지고 테스트가 어렵다. 그러나 DI 컨테이너는 학습·설정·런타임 마법 비용이 있다.

### Context
조립 지점이 사실상 `activate` 한 곳. 모듈 수는 많지만 의존 그래프는 명시적. 테스트는 순수 함수 + 가짜 주입으로 충분.

### Options Considered
1. **DI 컨테이너(tsyringe 등)** — 자동 해석/수명관리, 그러나 의존성·매직·디버깅 비용.
2. **싱글톤 남발** — 간단하나 테스트 격리 불가, 숨은 결합.
3. **수동 주입 + 인터페이스/함수 추상화** — 명시적, 무의존, 테스트 용이.

### Chosen Solution
3번. 생성자 옵션 객체(`new AgentExecutor(ctx, {...})`), 함수 타입 주입(`CritiqueLlmCall`), getter 주입(`getProvider`). 전역이 본질인 자원만 싱글톤(lock/queue) [S1][S2].

### Why It Was Chosen
조립이 한 곳이라 컨테이너의 이득이 작고, 수동 주입이 흐름을 가장 투명하게 만든다. 함수 주입으로 검증 모듈을 순수하게 유지(테스트 시 가짜 LLM).

### Benefits
무의존·투명한 조립, 뛰어난 테스트성, 명시적 의존 그래프, 교체 용이.

### Drawbacks
조립 코드가 장황(activate 가 큼), 의존이 늘면 수동 배선 부담, 수명관리 직접.

### Future Risks
모듈/조립 지점이 폭증하면 수동 배선이 한계 → 부분적 컨테이너 도입 필요. 싱글톤은 테스트 격리를 점점 어렵게.

### Alternative Approaches
규모 확대 시 경량 컨테이너 또는 팩토리 레이어. 또는 기능별 "composition root" 를 여러 개로 분리.

## ⚖️ 모순 및 업데이트 (Contradictions & updates)
"엔터프라이즈엔 DI 컨테이너" 통념과 다르다 — 단일 composition root 소규모에선 수동 주입이 더 단순·명확. 규모가 결정 인자.

## 🛠️ 적용 사례 (Applied in summary)
`extension.ts`(수동 조립), `services.ts`(인터페이스), `criticAgent.ts`(함수 주입) [S1][S2][S3].

## 🔗 지식 그래프 (Knowledge Graph)
- **상위/루트:** [[AstraAI 아키텍처 개요]]
- **관련 개념:** [[의존성 주입과 서비스 인터페이스]], [[Repository Pattern]], [[엔지니어링 트레이드오프 분석]]
- **참조 맥락:** 로컬 LLM 이 "DI 컨테이너 vs 수동 주입" 을 규모 기준으로 결정할 때 참조.

## 📚 출처 (Sources)
- [S1] AstraAI/src/extension.ts — activate 수동 조립, getter/옵션 주입
- [S2] AstraAI/src/core/services.ts — IAIService/IBrainService
- [S3] AstraAI/src/intelligence/criticAgent.ts — CritiqueLlmCall 함수 주입

## 📝 변경 이력 (Change history)
- 2026-06-13: AstraAI 코드 분석 기반 ADR 작성.
