서비스 수명: Transient, Scoped, Singleton
Transient, Scoped, Singleton 수명이 객체 생성, 공유, 폐기에 어떤 영향을 주는지 배웁니다.
서비스 수명: Transient, Scoped, Singleton은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
서비스 수명이 중요한 이유
서비스 수명은 인스턴스가 얼마나 오래 유지되는지와 몇 개의 인스턴스가 생성되는지를 제어합니다. 잘못된 수명을 선택하면 요청 간 데이터 유출이나 과도한 객체 생성 같은 미묘한 버그가 발생합니다.
일시적 수명: 매번 새로 생성
일시적 서비스는 컨테이너에서 요청될 때마다 새로 생성됩니다. 상태를 공유하면 위험할 수 있는 가볍고 상태가 없는 서비스에 사용하십시오.
builder.Services.AddTransient<IEmailSender, SmtpEmailSender>();
// Each resolution creates a new instance:
// var a = sp.GetRequiredService<IEmailSender>(); // new
// var b = sp.GetRequiredService<IEmailSender>(); // new (different)범위 지정 수명: 요청마다 한 번
범위 지정 서비스는 각 범위마다 한 번 생성되며, ASP.NET Core에서는 일반적으로 하나의 HTTP 요청이 하나의 범위에 해당합니다. 하나의 요청 안에서는 동일한 인스턴스를 공유하고, 다음 요청에서는 새 인스턴스를 생성합니다.
builder.Services.AddScoped<AppDbContext>();
// Within a single HTTP request:
// Both resolve to the SAME AppDbContext instance
// -> consistent unit of work across the request싱글턴 수명: 애플리케이션 수명 동안 하나
싱글턴 서비스는 한 번 생성된 후 애플리케이션의 전체 수명 동안 재사용됩니다. 생성 비용이 높고 스레드 안전한 구성 캐시 같은 서비스에 사용하십시오.
builder.Services.AddSingleton<IMemoryCache, MemoryCache>();
// Or register a pre-built instance:
var config = new AppConfig { MaxRetries = 3 };
builder.Services.AddSingleton<IAppConfig>(config);세 가지 수명 비교
다음은 세 가지 수명을 나란히 비교한 내용입니다:
- 일시적 — 요청마다 새 인스턴스 생성, 상태가 없는 유틸리티
- 범위 지정 — HTTP 요청마다 하나, DbContext, 작업 단위
- 싱글턴 — 애플리케이션 수명 동안 하나, 캐시, 구성
수명 포획 의존성 문제
범위 지정 또는 일시적 서비스를 싱글턴에 주입하는 것은 흔한 실수입니다. 싱글턴이 수명이 짧은 서비스에 대한 참조를 보유하면 해당 서비스가 지나치게 오래 유지됩니다.
// BAD: Singleton captures a Scoped service
public class MySingleton
{
private readonly AppDbContext _db; // Scoped!
public MySingleton(AppDbContext db) => _db = db;
// _db is now stuck alive for the app's lifetime
}범위 위반 감지
수명 포획 의존성이 감지되면 컨테이너가 시작 시 예외를 발생시키도록 ValidateScopes를 활성화하십시오. 이렇게 하면 운영 환경에서 데이터 버그가 발생하기 전에 실수를 찾아낼 수 있습니다.
builder.Host.UseDefaultServiceProvider(options =>
{
options.ValidateScopes = true; // detect captive deps
options.ValidateOnBuild = true; // fail fast at start
});요청 외부에서 범위 지정 서비스 사용
백그라운드 작업에서 범위 지정 서비스를 해결하려면 IServiceScopeFactory를 사용하여 명시적인 범위를 생성하십시오. 루트 컨테이너에서 범위 지정 서비스를 직접 해결하지 마십시오.
public class MyWorker : BackgroundService
{
private readonly IServiceScopeFactory _factory;
public MyWorker(IServiceScopeFactory factory) => _factory = factory;
protected override async Task ExecuteAsync(CancellationToken ct)
{
using var scope = _factory.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
await db.Users.ToListAsync(ct);
}
}일시적 수명의 삭제 가능한 서비스
루트 컨테이너에서 해결한 일시적 수명의 IDisposable 서비스는 컨테이너가 삭제될 때까지(애플리케이션 종료 시점까지) 추적됩니다. 리소스를 신속하게 해제하려면 범위 내부에서 해결하십시오.
// Correctly scoped transient disposable
using var scope = sp.CreateScope();
var svc = scope.ServiceProvider.GetRequiredService<MyDisposableService>();
await svc.DoWorkAsync();
// svc.Dispose() called when scope is disposed올바른 수명 선택
간단한 선택 가이드입니다:
- 서비스에 상태가 없나요? → 일시적
- 요청에 의존하나요(예: 사용자 ID, DbContext)? → 범위 지정
- 스레드 안전하며 생성 비용이 높은가요? → 싱글턴
실전 예제: 세 가지 수명 함께 사용하기
일반적인 웹 API는 정확성과 성능을 위해 각 서비스에 적절한 수명을 지정하여 등록합니다.
builder.Services.AddSingleton<IConfiguration>(builder.Configuration);
builder.Services.AddSingleton<ICacheService, RedisCacheService>();
builder.Services.AddScoped<AppDbContext>();
builder.Services.AddScoped<IOrderRepository, OrderRepository>();
builder.Services.AddScoped<OrderService>();
builder.Services.AddTransient<IEmailSender, SendGridEmailSender>();빠른 확인
싱글턴 서비스가 범위 지정 서비스에 대한 참조를 보유하면 어떤 문제가 발생할까요?
복습: 서비스 수명
핵심 요점:
- 일시적: 매번 새 인스턴스 생성, 상태가 없고 가벼운 서비스에 적합합니다
- 범위 지정: 요청마다 하나의 인스턴스, DbContext, 리포지토리, 작업 단위에 적합합니다
- 싱글턴: 애플리케이션 수명 동안 하나의 인스턴스, 캐시, 구성, 스레드 안전 유틸리티에 적합합니다
- 수명이 짧은 서비스를 수명이 더 긴 서비스에 주입하지 마십시오(수명 포획 의존성)
- 백그라운드 작업에서 범위 지정 서비스를 해결하려면
IServiceScopeFactory를 사용하십시오
자주 묻는 질문
“서비스 수명: Transient, Scoped, Singleton” 강의는 무료인가요?
네 — “서비스 수명: Transient, Scoped, Singleton” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“서비스 수명: Transient, Scoped, Singleton”에서 뭘 배우나요?
Transient, Scoped, Singleton 수명이 객체 생성, 공유, 폐기에 어떤 영향을 주는지 배웁니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
C# Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“서비스 수명: Transient, Scoped, Singleton” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- DI 컨테이너 기초
- 서비스 수명: Transient, Scoped, Singleton
- 생성자 주입과 인터페이스
- 팩터리와 옵션 패턴