의존성 : 객체가 자신의 기능을 수행하기 위해 필요한 다른 객체나 구성 요소
주입 : 객체가 필요한 의존성을 외부에서 제공받는 과정
의존성 주입 : 객체가 자신의 기능을 수행하기 위해 필요한 다른 객체나 구성요소를 외부에서 제공 받는 과정
- 예시: 컴포넌트를 드래그 드롭으로 스크립트에 연결하는 것도 넓은 의미에서 의존성 주입
의존성 주입 코드 예제
-
아래 Attack 메서드가 BaseAttack 메서드를 의존하고 있다.

-
아래 Attack 메서드는 BaseAttack(),SpecialAttack(),MagicAttack()를 의존하고 있다.


Attack메서드 안에 여러 메서드를 의존하게 되면 유지 보수가 상당히 어려워진다.
- 특히 switch문에서 어떤 상태에 따른 조건이 존재하고, 조건에 따른 메서드를 개별로 호출해야 한다면 유지보수가 상당히 어려워진다. 상태가 늘어날 수록 메서드 호출도 많아지기 때문에.
- 해결하기 위해 아래와 같이 한다.

의존성 주입은 하되, 유지보수 높이는 방법 : 인터페이스에 의존한다.
public interface IAttackType
{
public void Attack();
}
- 인터페이스의 객체를 만들고 , Attack메서드에서 attackType에 맞는 Attack 메서드를 호출한다.
public class Player : MonoBehaviour
{
private IAttackType attackType;
public void SetAttackType(IAttackType _attackType)
{
attackType = _attackType;
}
public void Attack()
{
attackType.Attack();
}
}
- 의존적이였던 BaseAttack()가 아니라, BaseAttack 클래스를 만들어서 인터페이스를 상속 받게 하여 Attack 메서드를 구현하게 한다.
- 나머지 MagicAttack(), SpecialAttack() 들도 각각 클래스로 만들어서 아래처럼 진행한다.

-
- 플레이어 클래스 객체에 접근하여 각 Attack 클래스의 인스턴스를 넘긴다.

-
- 할당
-
Player 클래스에 인터페이스를 객체로 선언했었다.
-
할당해야 될 타입은 BaseAttack, MagicAttack , SpecialAttack 이였지만, 해당 Attack클래스들 모두 인터페이스를 상속 받고 있기 때문에 할당이 가능하다.

생성자 주입 : 객체가 생성될 떄 생성자를 통해 필요한 의존성을 주입

- 생성자에서 인터페이스 타입을 받는 형태이다.
- 위 사진을 보면 Player5는 모노비해비어를 상속 받고 있지 않다. 유니티에서는 new 키워드와 생성자를 이용하려면 모노비해비어를 제거해야 한다. 만약 추가하면 유니티 콘솔창에서 경고창이 뜬다. 유니티 추천 X
필드 주입 : 필드에 직접 필요한 의존성을 주입

- DITest2 클래스에서 Player6 클래스에 멤버 변수이자 필드인 인터페이스 변수의 값을 변경한다.
- 가장 간단해서 편하긴 하지만, 유지 보수가 힘들어질 수 있다. 필드 주입을 바로 해버리면 수정하거나 그럴 때 힘들 수 있다.
메서드 주입: 메서드로 필요한 의존성을 주입
- 위 코드에서 설명한 것이 메서드 주입이였다.
- 번거롭지만, 필요없는 메서드를 만들어야해서 좀 그렇지만 프로퍼티 주입이 좋다.
프로퍼티 주입 : 프로퍼티로 필요한 의존성을 주입. 메서드 주입의 향상된 버전

- 프로퍼티는 set만 할 수 있으므로 함수 역할(매개변수 받고 변경하는거)처럼 이용할 수 있음