[ASP.NET Core] 종속성 주입

참조


목적

  • ASP.NET Core는 클래스와 해당 종속성 간의 IoC 를 실현하는 기술인 DI(종속성 주입) 소프트웨어 디자인 패턴을 지원합니다.
  • ASP.NET Core 의 종속성 주입에 대하여 학습 합니다.

종속성 주입 개요

  • 종속성은 다른 개체가 종속된 개체입니다.
  • 다른 클래스가 종속된 MyDependency 클래스에서 WrtieMessage 메서드를 사용하는 다음 코드가 있습니다.
public class MyDependency
{
    public void WriteMessage(string message)
    {
        Console.WriteLine($"MyDependency.WriteMessage called. Message: {message}");
    }
}
  • 클래스에서 MyDependency 클래스의 인스턴스를 만들어 WriteMessage 메서드를 사용할 수 있습니다.
  • 다음 예제에서 MyDependency 클래스는 IndexModel 클래스의 종속성입니다.
public class IndexModel : PageModel
{
    private readonly MyDependency _dependency = new MyDependency();

    public void OnGet()
    {
        _dependency.WriteMessage("IndexModel.OnGet");
    }
}
  • 이 클래스는 MyDependency 클래스를 만들고 이 클래스에 직접 종속됩니다.
  • 이전 예제와 같은 코드 종속성은 문제가 있으며 다음과 같은 이유로 사용하면 안됩니다.
    • MyDependency 를 다른 구현으로 바꾸려면 IndexModel 클래스를 수정해야 합니다.
    • MyDependency 에 종속성이 있으면 IndexModel 클래스에서 해당 종속성도 구성해야 합니다. 여러 클래스가 MyDependency 에 종속되어 있는 대형 프로젝트에서는 구성 코드가 앱 전체에 분산됩니다.
    • 이 구현은 단위 테스트 하기가 어렵습니다.
  • 종속성 주입은 다음과 같이 위 문제를 해결할 수 있습니다.
    • 인터페이스 또는 기본 클래스를 사용하여 종속성 구현을 추상화 합니다.
    • 서비스 컨테이너에 종속성 등록, ASP.NET Core 서비스 컨테이너인 IServiceProvider 를 기본 제공합니다. 서비스는 일반적으로 앱의 Program.cs 파일에 등록합니다.
    • 서비스가 사용되는 클래스의 생성자에 주입됨. 프레임워크가 종속성의 인스턴스를 만들고 더 이상 필요하지 않으면 삭제하는 작업을 담당합니다.
public interface IMyDependency
{
    void WriteMessage(string message);
}
  • 이 인터페이스는 구체적인 형식 MyDependency 에서 구현됩니다.
public class MyDependency : IMyDependency
{
    public void WriteMessage(string message)
    {
        Console.WriteLine($"MyDependency.WriteMessage Message: {message}");
    }
}
  • 위 예제에서는 IMyDependency 서비스를 구체적인 MyDependency 형식으로 등록합니다.
  • AddScoped 메서드는 단일 요청의 수명인 범위가 지정된 수명으로 서비스를 등록합니다.
using DependencyInjectionSample.Interfaces;
using DependencyInjectionSample.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

// 종속성 주입
builder.Services.AddScoped<IMyDependency, MyDependency>();

var app = builder.Build();
  • 샘플 앱에서는 IMyDependency 서비스가 요청되며 이 서비스는 WriteMessage 메서드를 호출하는 데 사용됩니다.
public class Index2Model : PageModel
{
    private readonly IMyDependency _myDependency;

    // DI는 반드시 생성자를 통하여 주입해야 합니다.
    public Index2Model(IMyDependency myDependency)
    {
        _myDependency = myDependency;            
    }

    public void OnGet()
    {
        _myDependency.WriteMessage("Index2Model.OnGet");
    }
}
  • IMyDependency 인터페이스의 구현을 기본 제공 로깅 API를 사용할 수도 있습니다.
public class MyDependency2 : IMyDependency
{
    private readonly ILogger<MyDependency2> _logger;

    public MyDependency2(ILogger<MyDependency2> logger)
    {
        _logger = logger;
    }

    public void WriteMessage(string message)
    {
        _logger.LogInformation( $"MyDependency2.WriteMessage Message: {message}");
    }
}
  • 업데이트 된 Programcs는 새 IMyDependency 구현을 등록합니다.
using DependencyInjectionSample.Interfaces;
using DependencyInjectionSample.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddScoped<IMyDependency, MyDependency2>();

var app = builder.Build();
  • MyDependency2는 생성자에서 요청하는 ILogger<TCategoryName> 에 종속됩니다.
  • ILogger<TCategroyName> 은 프레임워크에서 제공하는 서비스입니다.
  • 종속성 주입을 연결된 방식으로 사용하는 일은 특별한 경우가 아닙니다.
  • 요청된 각 종속성은 차례로 자체 종속성을 요청합니다.
  • 컨테이너는 그래프의 종속성을 해결하고 완전히 해결된 서비스를 반환합니다.
  • 해결해야 하는 종속성이 모인 집합은 일반적으로 종속성 트리, 종속성 그래프 또는 개체 그래프라고 합니다.
  • 종속성 주입 용어에서 서비스는 다음과 같습니다.
    • 일반적으로 다른 개체에 IMyDependency 서비스와 같은 서비스를 제공하는 개체입니다.
    • 서비스에서 웹 서비스를 사용할 수 있지만 웹 서비스와 관련 있는 것은 아닙니다.
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY