DI
ASP.NeT Core
에서 DI는 의존성 주입을 위한 프레임워크임
DI
는 소프트웨어 개발에서 중요한 디자인 패턴 중 하나이며, 코드의 유연성과 재사용성을 증가시키고 의존성 관리를 용이하게함.
DI
컨테이너는 서비스를 등록하고 필요한 곳에서 이를 주입하여 사용할 수 있도록 지원함.
최초 어플리케이션이 실행됬을 때, 동작하는 미들웨어에서 DI
서비스 등록을 통해 소스 어디서든 주입만 하면 사용이 가능함
DI
생명주기를 통해 개발자는 클래스 간의 의존성을 직접 관리할 필요 없이, DI
컨테이너가 이를 대신 처리함. (가비지 컬렉터?!)
DI
기능은 개발자가 더 효율적으로 코드를 구성하고 관리할 수 있도록 해줌. DI
컨테이너에 서비스 등록만 해두면 다양한 프로세스에서 효율적으로 사용할 수 있기 때문이지!
책에서 말하는 좋은 프로그래밍은 객체 간의 결합도를 낮추는 것이라 표현하는데 DI는 이를 어느정도 해소 시켜줌.
DI 구성 단계
서비스 등록
DI
컨테이너에 서비스를 등록하고 이를 주입을 통해서 사용한다고 했음.
첫 단계가 서비스를 DI 컨테이너에 등록하는 거임.
이 과정에서 서비스의 생명 주기와 구현체를 지정하게 됌.
ASP.NET Core
에서는 program.cs
에서 지정 가능함. (Core 6.0
부터 Startup.cs
사라짐 ㅋ)
5.0 버전에서는 Startup.cs
에서 DI
주입했음.
6.0 이후 버전 부터는 Program.cs
에서 주입하면 됌.
// ASP.NET Core 5.0
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddScoped<Taco>(); // 요기 DI
}
// ASP.NET Core 8.0
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddScoped<Taco>(); // 요기 DI
var app = builder.Build();
의존성 주입
서비스가 필요한 클래스나 컴포넌트에 대해 DI 컨테이너가 해당 서비스(클래스)의 인스턴스를 제공하는 프로세스임
여기서 말하는 서비스는 클래스 단계임. 컨테이너에 등록된 서비스를 특정 프로세스에서 주입 받아 사용 한다는 개념을 기억하잣
생명 주기
서비스의 인스턴스가 유지되는 시간을 의미함. ASP.NET Core
에서는 Transient
, Scoped
, Singleton
3가지 생명 주기를 사용함.
Transient
매번 서비스가 요청될 때마다 새로운 인스턴스를 생성함.
Scoped
HTTP 같은 프로세스 내에서는 같은 인스턴스를 공유함.
Singleton
어플리케이션 전체에 걸쳐 단일 인스턴스!!
생성과 소멸 과정에서 오직 1개만 존재하는 유니크한 녀석임.
DI 예제
우선 Interface
를 생성함. 클래스로도 주입이 가능하나 인터페이스를 주입하는 이유에 대해서는 끝에 설명 하겠음.
Interface
추상 이므로 구현체가 항상 함께 등록되어야함. Interface
만 등록하면 구현체를 찾을 수 없었어서 에러를 맛볼 것임 ㅋ
인터페이스 이름은 ITaco
임. 인터페이스를 선언할 때는 항상 앞에 I
를 붙혀주도록 하자. MS에서 그리 시켰다!
public interface ITaco
{
string GetName(string name);
}
대상 클래스에 인터페이스를 상속 받고 구현체도 작성 해줌.
여기서 말하는 구현체는 인터페이스의 메서드를 의미함.
public class TacoService : ITaco
{
public string GetName(string name)
{
return name;
}
}
아래 소스가 DI
주입 소스임. 생각 보다 간단...!
앞에서 말했듯이 ASP.NET Core
버전에 따라 작성 경로가 다름. 6.0 버전 기준으로 이하면 Startup.cs
이상이면 Program.cs
에 작성해 주면 됌. 나는 8.0이라 Program.cs에 작성함. (최신 버전이 좋다!)
인자로는 인터페이스, 인터페이스를 상속받는 클래스를 넣어주면 됌.
builder.Services.AddScoped<ITaco, TacoService>();
왜 인터페이스를 넣는지 궁금하지 않을 수 없음. 사실 클래스만으로도 DI는 가능함.
But 우리는 다형성과 추상화를 통해 가독성을 향상 시키기 위해서 인터페이스를 사용함.
아래처럼 새로운 YourService
클래스에서 구현체를 재정의 했을 경우가 대표적임 예임.
public class YourService : ITaco
{
public string GetName(string name)
{
return "Your" + name;
}
}
DI
컨테이너에서 서비스를 호출하는 코드임.
필드 ITaco
를 선언하고 생성자를 통해서 의존성을 주입 받음.
public class HomeController : Controller
{
private readonly ITaco _taco;
public HomeController(ITaco taco)
{
_taco = taco;
}
public IActionResult Index()
{
Taco taco = new Taco();
taco.Name = _taco.GetName("서울 타코");
return View(taco);
}
}
결론
의존성 주입은 ASP.NET Core
핵심 기술 중 하나라 생각 한다.
최초 어플리케이션이 요청을 받을 때, 미들웨어 단계에서 DI
컨테이너 등록이 시작 되고 등록된 서비스를 생성자를 통해 주입 받아 사용 가능함.
'SW 기능 > .NET Core' 카테고리의 다른 글
BulkInsert (0) | 2024.02.08 |
---|---|
Razor (0) | 2024.02.06 |
Dapper (2) | 2024.02.06 |
Tag Helper (0) | 2024.02.06 |
Model Binding (1) | 2024.02.02 |