카테고리 없음

ASP.NET CORE 8 의 수명 Transient 사용 사례

재우니 2025. 1. 8. 23:42

 

세 가지 수명의 차이점 요약

 

다양한 Transient 사례를 통해 어떤 상황에서 이 수명이 적합한지 살펴보겠습니다.


1. 데이터 변환 및 포맷팅 서비스

  • 특징: 데이터 변환은 상태를 보존할 필요가 없으므로 Transient로 처리하기 적합.
  • 예시: 날짜, 문자열, 숫자 등의 포맷팅.
public interface IDataFormatter
{
    string FormatDate(DateTime date);
}

public class DataFormatter : IDataFormatter
{
    public string FormatDate(DateTime date)
    {
        return date.ToString("yyyy-MM-dd");
    }
}

// DI 등록
services.AddTransient<IDataFormatter, DataFormatter>();

2. 이메일 발송 서비스

  • 특징: 이메일은 단일 작업으로 끝나므로 인스턴스를 생성하고 바로 폐기하는 것이 적합.
  • 예시: SMTP 이메일 발송.
public interface IEmailService
{
    Task SendEmailAsync(string to, string subject, string body);
}

public class EmailService : IEmailService
{
    public async Task SendEmailAsync(string to, string subject, string body)
    {
        // SMTP 구성 및 이메일 전송 로직
        Console.WriteLine($"Email sent to {to} with subject {subject}");
        await Task.CompletedTask;
    }
}

// DI 등록
services.AddTransient<IEmailService, EmailService>();

3. 유효성 검사 (Validation)

  • 특징: 데이터의 유효성을 검사하는 서비스는 상태를 유지할 필요가 없으며 요청마다 새로운 인스턴스를 생성해도 무방.
  • 예시: DTO 검증.
public interface IValidator<T>
{
    bool Validate(T model);
}

public class UserValidator : IValidator<UserDto>
{
    public bool Validate(UserDto model)
    {
        return !string.IsNullOrEmpty(model.Email);
    }
}

// DI 등록
services.AddTransient<IValidator<UserDto>, UserValidator>();

4. 암호화 및 해시 처리

  • 특징: 암호화 작업은 독립적이며 상태를 유지하지 않으므로 Transient로 처리.
  • 예시: 비밀번호 해싱.
public interface IPasswordHasher
{
    string HashPassword(string password);
}

public class PasswordHasher : IPasswordHasher
{
    public string HashPassword(string password)
    {
        // 간단한 해싱 로직
        return Convert.ToBase64String(Encoding.UTF8.GetBytes(password));
    }
}

// DI 등록
services.AddTransient<IPasswordHasher, PasswordHasher>();

5. 요청 기반 보고서 생성

  • 특징: 보고서는 요청마다 다른 데이터를 처리하므로, 각 요청마다 새로운 인스턴스를 생성.
  • 예시: PDF 보고서 생성.
public interface IReportGenerator
{
    byte[] GenerateReport(string data);
}

public class ReportGenerator : IReportGenerator
{
    public byte[] GenerateReport(string data)
    {
        // PDF 생성 로직
        return Encoding.UTF8.GetBytes($"Report: {data}");
    }
}

// DI 등록
services.AddTransient<IReportGenerator, ReportGenerator>();

6. 알림 발송 서비스

  • 특징: 단발성 알림 발송 작업에 적합.
  • 예시: SMS 또는 Push 알림.
public interface INotificationService
{
    Task SendNotificationAsync(string userId, string message);
}

public class NotificationService : INotificationService
{
    public async Task SendNotificationAsync(string userId, string message)
    {
        // 알림 전송 로직
        Console.WriteLine($"Notification sent to {userId}: {message}");
        await Task.CompletedTask;
    }
}

// DI 등록
services.AddTransient<INotificationService, NotificationService>();

7. API 요청의 헤더 생성기

  • 특징: 외부 API 호출 시 동적으로 헤더를 생성하는 경우.
  • 예시: JWT 토큰 기반 인증 헤더 생성.
public interface IApiRequestHeaderBuilder
{
    IDictionary<string, string> BuildHeaders(string token);
}

public class ApiRequestHeaderBuilder : IApiRequestHeaderBuilder
{
    public IDictionary<string, string> BuildHeaders(string token)
    {
        return new Dictionary<string, string>
        {
            { "Authorization", $"Bearer {token}" },
            { "Content-Type", "application/json" }
        };
    }
}

// DI 등록
services.AddTransient<IApiRequestHeaderBuilder, ApiRequestHeaderBuilder>();

8. 특정 작업 단위의 이벤트 처리

  • 특징: 작업 단위로 새로운 이벤트 처리 인스턴스 생성.
  • 예시: 도메인 이벤트 핸들러.
public interface IEventHandler<TEvent>
{
    Task HandleAsync(TEvent @event);
}

public class UserCreatedEventHandler : IEventHandler<UserCreatedEvent>
{
    public async Task HandleAsync(UserCreatedEvent @event)
    {
        // 이벤트 처리 로직
        Console.WriteLine($"User Created: {@event.UserId}");
        await Task.CompletedTask;
    }
}

// DI 등록
services.AddTransient<IEventHandler<UserCreatedEvent>, UserCreatedEventHandler>();

9. 가볍고 자주 호출되는 서비스

  • 특징: 계산 또는 필터링 같은 가벼운 작업 서비스.
  • 예시: 데이터 필터링.
public interface IDataFilter
{
    IEnumerable<T> Filter<T>(IEnumerable<T> data, Func<T, bool> predicate);
}

public class DataFilter : IDataFilter
{
    public IEnumerable<T> Filter<T>(IEnumerable<T> data, Func<T, bool> predicate)
    {
        return data.Where(predicate);
    }
}

// DI 등록
services.AddTransient<IDataFilter, DataFilter>();

10. 로깅 메시지 포맷터

  • 특징: 로그 메시지를 특정 형식으로 포맷팅.
  • 예시: 로그 포맷터.
public interface ILogFormatter
{
    string FormatLog(string message, LogLevel level);
}

public class LogFormatter : ILogFormatter
{
    public string FormatLog(string message, LogLevel level)
    {
        return $"{level}: {DateTime.UtcNow} - {message}";
    }
}

// DI 등록
services.AddTransient<ILogFormatter, LogFormatter>();

요약

Transient는 아래와 같은 서비스에 적합합니다:

  1. 상태 비저장: 요청마다 독립적으로 동작해야 하는 서비스.
  2. 가벼운 작업: 데이터 변환, 검증, 포맷팅 등 간단한 작업.
  3. 단발성 작업: 보고서 생성, 이메일/SMS 발송 등.

예외적인 경우를 제외하면 상태를 공유하거나 무거운 리소스를 다루는 서비스에는 적합하지 않습니다.