[C#] Singleton, Scoped, Transient 차이점 – DI Container 생명주기 완전 정리
C#에서 의존성 주입(Dependency Injection)을 사용할 때,
DI Container에 등록할 수 있는 Singleton
, Scoped
, Transient
는 각기 다른 생명주기를 가지고 있습니다.
실무에서 자주 쓰이는 이 3가지 생명주기의 차이점과 사용 시 주의할 점,
그리고 예제를 통한 설명을 함께 정리해보겠습니다.
🔁 1. Singleton – 앱 전체에서 단 하나
Singleton으로 등록된 서비스는 애플리케이션 실행 동안 딱 1개 인스턴스만 생성되어, 모든 곳에서 공유됩니다.
// 등록 방법
services.AddSingleton<IMyService, MyService>();
- 처음 요청 시 1회 생성 → 이후 모든 요청에서 동일한 인스턴스 반환
- 상태를 유지해야 하는 캐시, 설정, Logger 등에 적합
주의: 상태 공유 때문에 Thread-Safe
하게 설계되어야 합니다.
🧩 2. Scoped – 요청(Request)당 하나
Scoped로 등록된 서비스는 HTTP 요청마다 새 인스턴스가 생성됩니다.
ASP.NET Core에서는 컨트롤러 단위로 공유되며, 동일 요청 안에서는 하나의 인스턴스가 사용됩니다.
// 등록 방법
services.AddScoped<IMyService, MyService>();
- 웹 요청마다 새로운 인스턴스 생성
- DBContext, 사용자 요청 데이터 처리에 적합
주의: 콘솔 앱이나 WinForms에서는 별도 Scope 관리가 필요합니다.
⚡ 3. Transient – 요청마다 새로 생성
Transient는 요청될 때마다 항상 새로운 인스턴스를 생성합니다.
의존 객체까지 전부 새로 만들어지기 때문에 가볍고 독립적인 서비스에 적합합니다.
// 등록 방법
services.AddTransient<IMyService, MyService>();
- 요청마다 새 인스턴스 생성 (심지어 같은 요청에서도 여러 번 생성 가능)
- 상태를 가지지 않는 Helper 클래스, 계산기, 포맷터 등에 적합
🔍 생명주기 비교 표
종류 | 인스턴스 수명 | 적합한 용도 |
---|---|---|
Singleton | 앱 전체에서 1개 | 설정, 캐시, 공통 서비스 |
Scoped | 요청(Request)당 1개 | DBContext, 사용자 세션 |
Transient | 요청마다 새로 | Helper, Utility, Stateless 서비스 |
🧠 실무 팁 – 언제 어떤 생명주기를 써야 할까?
- Singleton – 상태를 공유해도 문제가 없는 서비스 (예: 로깅, 캐시)
- Scoped – 요청 기반의 리소스를 다룰 때 (예: DbContext)
- Transient – 가벼운 서비스, 상태가 없는 도구성 클래스
잘못된 생명주기를 적용하면 의도하지 않은 상태 공유나 메모리 낭비가 발생할 수 있습니다.
따라서 서비스의 역할과 범위에 따라 생명주기를 신중하게 선택해야 합니다.
📌 마무리
의존성 주입(DI)은 유지보수성과 테스트 용이성을 높여주는 핵심 기술입니다.
그만큼 생명주기를 제대로 이해하고 사용하는 것이 중요합니다.
이 글이 도움이 되셨다면 공감 / 댓글 부탁드립니다 😊
반응형
'프로그래밍 > C#' 카테고리의 다른 글
[C#] Devexpress GridControl DataSource 지연 로딩으로 속도 최적화하기 (0) | 2025.03.24 |
---|---|
[C#] DevExpress WinForms GridView 속도 개선 팁 – 렌더링 최적화 & 클릭 지연 해결 (0) | 2025.03.24 |
[C#] Singleton 패턴 잘못 쓰면 발생하는 문제 – 메모리 누수 & DI 문제 (0) | 2025.03.24 |
[C#] 디자인 패턴 - 실무에서 가장 많이 쓰는 디자인 패턴 3가지 정리 (Singleton, Factory, Command) (0) | 2025.03.21 |
[C#] Winform/Devexpress GridView DoubleClick Event (0) | 2023.06.29 |