[ASP.NET Core] 서비스 생명주기 예제

참고


목적

  • ASP.NET Core 서비스에서는 총 3가지의 생명주기가 있습니다.
  • Singleton, Scoped, Transient 3가지의 생명주기가 있는데 해당 생명주기의 차이점을 보다 명확하게 이해하기 위해 예제 코드를 작성해 알아 보도록 하겠습니다.

Web API 프로젝트 생성

  • ASP.NET Core Web API 프로젝트 하나를 생성합니다.
  • 그런 다음 다음과 같은 클래스들을 작성해 줍니다.


Operation 클래스 추가

  • 다음으로 Operation.cs 클래스를 추가하고, 다음과 같이 코드를 작성해 줍니다.
namespace WebApplication2.Models
{
    public class Operation
    {
        public Guid OperationId { get; set; }
    }
}

Data 관련 클래스 추가

  • 다음으로, OperationData.cs, IOperationData.cs 2개의 클래스, 인터페이스를 생성합니다.
  • 그리고 아래와 같이 코드를 작성합니다.
using WebApplication2.Models;

namespace WebApplication2.Data
{
    public class OperationData : IOperationData, IOperationTransient, IOperationScoped, IOperationSingleton
    {
        Guid _guid;
        public OperationData() : this(Guid.NewGuid())
        {

        }

        public OperationData(Guid guid)
        {
            _guid = guid;
        }

        public Guid OperationId => _guid;
    }
}
namespace WebApplication2.Data
{
    public interface IOperationData
    {
        Guid OperationId { get; }
    }

    public interface IOperationTransient : IOperationData
    {
    }

    public interface IOperationScoped : IOperationData
    {
    }

    public interface IOperationSingleton : IOperationData
    {
    }
}

서비스

  • 다음은 OperationService.cs 클래스를 생성하고 다음과 같이 코드를 작성합니다.
using WebApplication2.Data;

namespace WebApplication2.Services
{
    public class OperationService
    {
        public IOperationTransient TransientOperation { get; }
        public IOperationScoped ScopedOperation { get; }
        public IOperationSingleton SingletonOperation { get; }

        public OperationService(IOperationTransient transientOperation,
            IOperationScoped scopedOperation,
            IOperationSingleton singletonOperation)
        {
            TransientOperation = transientOperation;
            ScopedOperation = scopedOperation;
            SingletonOperation = singletonOperation;
        }
    }
}

컨트롤러 추가

  • 다음은 OperationsController.cs 클래스를 생성하고 아래와 같이 코드를 작성합니다.
using Microsoft.AspNetCore.Mvc;
using WebApplication2.Data;
using WebApplication2.Models;
using WebApplication2.Services;

namespace WebApplication2.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class OperationsController : ControllerBase
    {
        private readonly OperationService _operationService;
        private readonly IOperationTransient _transientOperation;
        private readonly IOperationScoped _scopedOperation;
        private readonly IOperationSingleton _singletonOperation;

        public OperationsController(OperationService operationService,
            IOperationTransient transientOperation,
            IOperationScoped scopedOperation,
            IOperationSingleton singletonOperation)
        {
            _operationService = operationService;
            _transientOperation = transientOperation;
            _scopedOperation = scopedOperation;
            _singletonOperation = singletonOperation;
        }

        // GET: api/<BlogController>
        [HttpGet]
        public ActionResult<IEnumerable<Operation>> Get()
        {
            var transient_guid = _transientOperation.OperationId;
            var scoped_guid = _scopedOperation.OperationId;
            var singleton_guid = _singletonOperation.OperationId;

            string a = $"transient : {transient_guid}";
            string b = $"scoped : {scoped_guid}";
            string c = $"singleton : {singleton_guid}";

            var os_transient_guid = _operationService.TransientOperation.OperationId;
            var os_scoped_guid = _operationService.ScopedOperation.OperationId;
            var os_singleton_guid = _operationService.SingletonOperation.OperationId;

            string a2 = $"transient : {os_transient_guid}";
            string b2 = $"scoped : {os_scoped_guid}";
            string c2 = $"singleton : {os_singleton_guid}";

            List<string> result = new List<string>()
            {
                a,b,c,
                a2,b2,c2
            };

            return Ok(result);
        }
    }
}

서비스

  • 마지막으로 시작 부분에 앞서 생성하였던 서비스들을 등록합니다.
  • 서비스를 등록하는 코드는 다음과 같습니다.
builder.Services.AddTransient<IOperationTransient, OperationData>();
builder.Services.AddScoped<IOperationScoped, OperationData>();
builder.Services.AddSingleton<IOperationSingleton, OperationData>();
builder.Services.AddTransient<OperationService, OperationService>();

실행 결과

  • 이제 Transient, Scoped, Singleton 의 차이를 알아 보기 위한 코드 준비는 완료 되었습니다.
  • 실제로 프로그램을 실행 한 후, Transient, Scoped, Singleton 의 차이점을 알아 보겠습니다.

첫 번째 Request

  • 현재 위 프로젝트는 1개의 Request 를 요청하였고, 총 2개의 서비스가 동작하여 GUID 가 생성된 모습니다.
  • Transient 같은 경우에는 1개의 Request 에서 서로 다른 2개의 서비스를 사용할 떄, 해당 서비스 각각의 새로운 객체를 생성합니다. 때문에, GUID 값이 서로 다른 것을 확인할 수 있습니다.
  • Scoped 같은 경우에는 1개의 Request 에서 서로 다른 2개의 서비스를 사용할 떄, 해당 서비스의 객체는 동일합니다. 때문에 GUID 값이 같습니다.
  • Singleton 은 단일 객체이기 때문에 1개의 Request 에서 서로 다른 2개의 서비스를 사용할 때, GUID가 같습니다.


두 번째 Request

  • 다음으로는 다시 2번째 Request 를 요청하였고, 아래는 그 결과입니다.
  • Transient 는 첫 번째 Request 의 GUID 에서 모든 서비스 마다 객체가 새롭게 생성되어 GUID가 변경된 것을 확인할 수 있습니다.
  • Scoped 같은 경우, 같은 Request 범위 내에서는 같은 객체를 공유하지만, 새로운 Request 에서는 새롭게 객체가 생성되어 GUID 값이 첫 번째 GUID 와 다른 것을 확인할 수 있습니다.
  • Singleton 은 단일 객체이기 때문에, 2번 째 Request 여도 여전히 같은 객체를 사용하고, GUID 도 첫 번째 Request 의 GUID와 같은 것을 확인할 수 있습니다.

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY