의존성이란
의존성이라는 것은 A가 B에 의존할 경우 B가 변경될 때 A도 변경될 수 있는 가능성이 있다는 뜻입니다.
의존성 주입 (Dependency Injection)
의존성 주입이란 외부에서 객체를 생성하여 넘겨주는 것을 의미합니다.
예를들어 A 클래스가 B 클래스를 의존할 때,
B Object를 A가 직접 생성하지 않고 외부에서 생성하여 넘겨주면 의존성 주입했다고 합니다.
- 왼쪽은 A에서 B를 생성하는 일반적인 의존 형태이고, 오른쪽은 외부에서 의존 객체를 생성하고 주입하는 형태입니다.
- 의존성 주입은 소프트웨어 디자인 패턴 중 하나로, 클래스 간의 의존성을 외부에서 주입하는 방식을 의미합니다.
- 이를 통해 코드의 재사용성과 유연성을 높이며, 유닛 테스트와 확장성에도 도움을 줍니다.
As-Is 코드 (의존성 주입을 사용하지 않은 경우)
using System;
public class Logger
{
public void Log(string message)
{
Console.WriteLine($"[Log] {message}");
}
}
public class UserService
{
private readonly Logger _logger;
public UserService()
{
_logger = new Logger();
}
public void DoSomething()
{
// 비즈니스 로직 수행
_logger.Log("Something was done in the UserService.");
}
}
class Program
{
static void Main(string[] args)
{
UserService userService = new UserService();
userService.DoSomething();
}
}
- UserService 클래스가 Logger 클래스에 의존성을 갖고 있습니다.
- 이로 인해 UserService 클래스는 Logger 클래스에 강하게 결합되어 있으며, 유닛 테스트나 변경 사항에 취약합니다.
To-Be 코드 (의존성 주입을 적용한 경우)
using System;
public interface ILogger
{
void Log(string message);
}
public class Logger : ILogger
{
public void Log(string message)
{
Console.WriteLine($"[Log] {message}");
}
}
public class UserService
{
private readonly ILogger _logger;
public UserService(ILogger logger)
{
_logger = logger;
}
public void DoSomething()
{
// 비즈니스 로직 수행
_logger.Log("Something was done in the UserService.");
}
}
class Program
{
static void Main(string[] args)
{
ILogger logger = new Logger();
UserService userService = new UserService(logger);
userService.DoSomething();
}
}
- `UserService 클래스가 ILogger 인터페이스에 의존성을 주입받도록 변경되었습니다.
- 이로써 UserService와 Logger 사이의 결합도가 낮아졌습니다.
- 또한, Main 메서드에서는 ILogger 구현체를 생성하고 이를 UserService 생성자에 주입하는 방식을 사용합니다.
- 이렇게 하면 UserService 클래스는 로그 출력에 필요한 구체적인 구현 내용을 몰라도 되며,
- 다른 종류의 로깅 시스템을 사용하거나 변경하는 데 더 유연해집니다.
속성 주입(Property Injection)과 생성자 주입(Constructor Injection)은 의존성 주입의 다양한 형태 중 두 가지 주요한 형태입니다.
이 두 가지 형태는 각각 다른 방식으로 의존성을 주입하는 방법을 나타냅니다.
생성자 주입(Constructor Injection)
- 보통 생성자 주입이 의존성 주입을 구현하는 가장 권장되는 방식이며,
- 클래스의 상태가 객체 생성 이후 변경되지 않도록 보장하는 장점이 있습니다.
- 생성자 주입은 의존성을 주입할 때 클래스의 생성자를 통해 이루어지는 방식입니다.
- 클래스가 의존성을 생성자 매개변수로 받아들이고, 객체가 생성될 때 외부에서 의존성을 주입합니다.
- 생성자 주입은 클래스가 생성될 때 필요한 모든 의존성을 보장받을 수 있도록 해줍니다.
public class UserService
{
private readonly ILogger _logger;
public UserService(ILogger logger)
{
_logger = logger;
}
public void DoSomething()
{
// 비즈니스 로직 수행
_logger.Log("Something was done in the UserService.");
}
}
속성 주입(Property Injection)
- 속성 주입은 의존성을 주입할 때 클래스의 속성을 통해 이루어지는 방식입니다.
- 클래스가 외부 종속성을 갖는 공개 속성을 정의하고, 이 속성을 통해 의존성을 주입받습니다.
- 일반적으로 속성 주입은 필수적인 의존성이 아닌 선택적인 의존성을 주입할 때 사용될 수 있습니다.
public class UserService
{
public ILogger Logger { get; set; }
public void DoSomething()
{
// 비즈니스 로직 수행
Logger?.Log("Something was done in the UserService.");
}
}
'프로그래밍 > C#' 카테고리의 다른 글
[C#] 디자인패턴-싱글톤 패턴(Singleton Pattern) (0) | 2022.07.03 |
---|---|
[C#] ? 와 ?? 연산자 (0) | 2022.06.22 |
[C#] 람다연산자 => (0) | 2022.06.06 |
[C#] 오버라이딩이란? (Override) (0) | 2022.06.06 |
[C#] 키워드 정리 (0) | 2022.06.06 |