IServiceScopeFactory 란?
IServiceScopeFactory 는 ASP.NET Core의 의존성 주입(DI) 컨테이너에서 새로운 서비스 범위(Scope) 를 만들기 위한 팩토리 인터페이스입니다.
기본적으로 DI 컨테이너는 Singleton / Scoped / Transient 세 가지 생명주기를 제공합니다.
일반적으로 Scoped 서비스는 HTTP 요청(Request)마다 생성되고, 요청이 끝나면 해제됩니다.
하지만 BackgroundService, Singleton 클래스 안에서는 Scoped 서비스를 직접 DI 받을 수 없습니다.
이를 해결하기 위하여 IServiceScopeFactory 를 이용해 임시 Scope를 만들어서 Scoped 서비스를 안전하게 사용합니다.
| 구분 | Singleton | Scoped | Transient |
|---|---|---|---|
| 인스턴스 생성 시점 | 애플리케이션 시작 시 한 번 | HTTP 요청 시작 시 한 번 | 의존성 주입 요청 시마다 |
| 인스턴스 수명 | 애플리케이션 전체 수명 | HTTP 요청 수명 | 가장 짧은 수명 |
| 공유 범위 | 전체 애플리케이션에서 단일 인스턴스 공유 | 동일 HTTP 요청 내에서 동일 인스턴스 공유 | 매번 새로운 인스턴스 생성 |
| 사용 사례 | – 캐시 서비스 – 설정 관리자 – 로깅 서비스 | – DB Context – 사용자 세션 – 트랜잭션 관리 | – 경량 서비스 – 상태 없는 헬퍼 – 일회성 작업 |
| 주의사항 | 상태 저장 시 thread-safe 고려 필요 | 요청 간 상태 공유 불가 | 빈번한 생성으로 성능 영향 가능성 |
사용법
1. 기본적인 사용법
using (var scope = scopeFactory.CreateScope())
{
var myService = scope.ServiceProvider.GetRequiredService<MyScopedService>();
myService.DoSomething();
}
// scope.Dispose()가 호출되면서 MyScopedService도 정리됨
2. BackgroundService에서 DbContext 사용하기
public class MyWorker : BackgroundService
{
private readonly IServiceScopeFactory _scopeFactory;
public MyWorker(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
using var scope = _scopeFactory.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<MyDbContext>();
var users = await db.Users.ToListAsync(stoppingToken);
Console.WriteLine($"현재 사용자 수: {users.Count}");
await Task.Delay(5000, stoppingToken);
}
}
}
// MyDbContext 가 Scoped 로 등록되어 있어도 Worker에서 안전하게 사용 가능.
3. Scoped 서비스 임시 실행
public class ReportGenerator
{
private readonly IServiceScopeFactory _scopeFactory;
public ReportGenerator(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public void Generate()
{
using var scope = _scopeFactory.CreateScope();
var service = scope.ServiceProvider.GetRequiredService<ReportService>();
service.CreateDailyReport();
}
}
// ReportService 가 Scoped 로 등록되어 있어도 IServiceScopeFactory 를 사용해 특정 시점에만 실행 가능.
4. 여러 Scoped 서비스 조합
public class CleanupJob
{
private readonly IServiceScopeFactory _scopeFactory;
public CleanupJob(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task RunAsync()
{
using var scope = _scopeFactory.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<MyDbContext>();
var emailService = scope.ServiceProvider.GetRequiredService<EmailService>();
var expiredUsers = db.Users.Where(u => u.IsExpired).ToList();
db.Users.RemoveRange(expiredUsers);
await db.SaveChangesAsync();
await emailService.SendCleanupReport(expiredUsers.Count);
}
}
정리
IServiceScopeFactory는 Scoped 서비스의 생명주기를 직접 제어할 수 있게 해줍니다.- 주로 Singleton 객체나 BackgroundService 에서 Scoped 서비스를 안전하게 사용하기 위해 필요합니다.
CreateScope()로 범위를 열고, 작업이 끝나면 자동으로 Dispose 되어 메모리 누수 없이 관리됩니다.




개인적으로 농법 블로그에 `IServiceScopeFactory`가 나와 있긴 어이가 없지만, Scope라는 단어가 식물 생애주기 관리에도 유용하다는 점은 농법 농사에도 도움이 될지도 모르겠네요! 비료 주는 시점을 스코프에 맞춰 정확히 관리하면 농사 생산성이 폭발적일지도 모르겠죠! 개발자들이 이 기능을 찾을 때 농법 블로그에 먼지 쌓이는 건 아쉽지만, Scope 농법이라는 새로운 트렌드가 생길지도 모르겠네요! 😄hẹn giờ online