일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- MSSQL
- 애니메이션
- 함수
- MS-SQL
- listview
- MVVM
- Firebase
- 깃허브
- Binding
- spring boot
- 오류
- 자바스크립트
- HTML
- JavaScript
- GitHub
- 파이어베이스
- Animation
- .NET
- Flutter
- Maui
- AnimationController
- 리엑트
- 마우이
- 바인딩
- page
- React JS
- 닷넷
- db
- 플러터
- typescript
Archives
- Today
- Total
개발노트
3. [ASP .NET Core] 의존성 주입(DI), IoC 란 무엇인가? (with Simple Injector) 본문
서버 개발/ASP .NET Core
3. [ASP .NET Core] 의존성 주입(DI), IoC 란 무엇인가? (with Simple Injector)
mroh1226 2024. 11. 17. 01:48반응형
1. 의존성 주입(DI)란?
**의존성 주입(Dependency Injection)**은 객체 간의 의존성을 외부에서 주입하여 객체를 생성하고 관리하는 디자인 패턴입니다.
이를 통해 코드의 재사용성, 테스트 용이성, 유지 보수성을 높일 수 있습니다.
왜 DI를 사용하는가?
- 객체가 서로 강하게 결합(Coupling)되어 있으면 변경이 어렵습니다.
- 의존성을 분리하면 코드 변경과 테스트가 용이해집니다.
- 서비스, 리포지토리, 데이터베이스와 같은 의존성을 명확히 관리할 수 있습니다.
2. IoC란?
IoC(Inversion of Control, 제어의 역전)은 객체의 생성과 생명 주기를 개발자가 직접 관리하지 않고, 컨테이너 또는 프레임워크가 관리하는 것을 말합니다. (제어권이 컨테이너에게 있음)
이를 통해 코드가 DI 컨테이너에 제어를 위임하며, 객체 간 결합도를 낮출 수 있습니다.
IoC와 DI의 관계
IoC는 개념이고, DI는 이를 구현하는 방법 중 하나입니다.
3. Simple Injector란?
Simple Injector는 .NET 환경에서 사용 가능한 경량 DI 컨테이너입니다.
다른 DI 컨테이너(AutoFac, Ninject)와 비교하여 사용법이 단순하고, 성능이 뛰어난 것이 특징입니다.
4. 간단한 예제: DI와 Simple Injector 사용하기
예제 목표
- DI로 분리된 구조IOrderService와 OrderService 구현.
- OrderService → IProductService ← ProductService (Simple Injector 관리)
- Simple Injector를 이용해 의존성 주입 설정.
1) 서비스 정의
IProductService.cs
public interface IProductService
{
string GetProductName(int productId);
}
public class ProductService : IProductService
{
public string GetProductName(int productId)
{
return $"Product #{productId}";
}
}
IOrderService.cs
public interface IOrderService
{
void PlaceOrder(int productId);
}
public class OrderService : IOrderService
{
private readonly IProductService _productService;
// 의존성을 주입받는 생성자
public OrderService(IProductService productService)
{
_productService = productService;
}
public void PlaceOrder(int productId)
{
var productName = _productService.GetProductName(productId);
Console.WriteLine($"Order placed for: {productName}");
}
}
2) 컨테이너에 의존성 등록
Program.cs
using SimpleInjector;
class Program
{
static void Main(string[] args)
{
// 1. Simple Injector 컨테이너 생성
var container = new Container();
// 2. 의존성 등록
container.Register<IProductService, ProductService>();
container.Register<IOrderService, OrderService>();
// 3. 의존성 검증
container.Verify();
// 4. 의존성 해결 및 실행
var orderService = container.GetInstance<IOrderService>();
orderService.PlaceOrder(1);
Console.ReadLine();
}
}
- 클래스 분리
- IProductService는 제품 정보를 관리하고, IOrderService는 주문 정보를 관리합니다.
- OrderService는 IProductService를 의존하지만, 인터페이스를 통해 의존성을 분리했습니다.
- Simple Injector로 의존성 관리
- Container.Register<IProductService, ProductService>(): IProductService를 호출하면 ProductService의 인스턴스를 반환.
- Container.Register<IOrderService, OrderService>(): IOrderService를 호출하면 OrderService의 인스턴스를 반환하며, IProductService가 자동으로 주입됩니다.
- DI의 효과
- OrderService가 ProductService에 강하게 결합되지 않으므로, ProductService를 교체할 수 있습니다.
- MockProductService를 테스트 시 주입하여 별도의 단위 테스트 작성이 가능합니다.
- 이 구조의 장점
- 클래스 간 결합도 감소:
- OrderService는 IProductService 인터페이스에 의존하므로, 실제 구현체가 무엇인지 신경 쓰지 않습니다.
- 테스트 용이성:
- 다른 환경(Mock 등)에서 사용할 수 있는 대체 구현체를 주입할 수 있습니다.
- 확장성:
- 새로운 ProductService 구현체(예: DatabaseProductService)를 추가해도 OrderService는 수정할 필요가 없습니다.
- 코드의 재사용성 증가:
- 각 클래스는 자신의 책임에만 집중하므로, 독립적으로 재사용이 가능합니다.
- 클래스 간 결합도 감소:
6. DI를 사용한 설계의 장점
- 결합도 감소: 클래스 간 의존성을 명확히 분리.
- 유연성 증가: 인터페이스 교체가 용이.
- 테스트 용이성: Mock 객체 주입 가능.
단위 테스트를 위한 Mock 클래스를 주입하는 예시
Mock 클래스 생성
public class MockProductService : IProductService
{
public string GetProductName(int productId)
{
return $"Mock Product #{productId}";
}
}
테스트 코드에서 DI 주입
var container = new Container();
// 테스트 환경에서 MockProductService 등록
container.Register<IProductService, MockProductService>();
container.Register<IOrderService, OrderService>();
container.Verify();
var orderService = container.GetInstance<IOrderService>();
orderService.PlaceOrder(99); // Output: Order placed for: Mock Product #99
7. Simple Injector의 장점
- 간결한 코드: DI 컨테이너 설정이 쉽고 코드가 간단합니다.
- 성능 최적화: 다른 DI 컨테이너보다 빠른 속도를 제공합니다.
- 강력한 검증: 컨테이너 설정 시 잘못된 의존성을 미리 검증합니다.
- DI는 객체 간의 의존성을 외부에서 관리하여 코드 결합도를 줄이는 디자인 패턴입니다.
- IoC는 제어권을 컨테이너가 가져가는 방식으로, DI로 구현됩니다.
- Simple Injector는 .NET 환경에서 DI를 간단히 적용할 수 있는 경량 IoC 컨테이너입니다.
만약 DI를 사용하지 않는 다면..?
class Program
{
static void Main(string[] args)
{
// 직접 객체 생성 (강결합)
var orderService = new OrderService();
orderService.PlaceOrder("Laptop");
}
}
문제점
- OrderService가 변경되면 호출하는 모든 코드도 수정해야 합니다.
- 테스트 시 Mocking이 어려워집니다.
반응형
'서버 개발 > ASP .NET Core' 카테고리의 다른 글
5. [ASP .NET Core] IList 사용하기 (0) | 2024.11.17 |
---|---|
4. [ASP .NET Core] 의존성 역전 원칙 (DIP) (1) | 2024.11.17 |
2. [ASP .NET Core] 간단 API 만들기(with Dapper) (0) | 2024.11.10 |
1. [ASP .NET Core] 프로젝트 환경 세팅하기 (0) | 2024.11.10 |
Comments