순서

I. Dependency Injection(의존성 주입)
I-1. Dependency(의존성) 란?
I-2. Inversion Of Control (IOC)
II. Interface
III. 구현


I. Dependency Injection(의존성 주입)

 

결론
- 직접 객체들을 호출 하는 것이 아닌
  제 3자인 중앙 매개체(Interface)를 거쳐 객체를 호출 하는 것이다.
  -> 매개체로부터 "주입" 받는다.

- 컴파일시 객체 결정 -> 동적으로 결정

 

1. Dependency(의존성) 란?

개발할때 한 클래스에서 다른 클래스의 메소드를 사용하고 싶을 때
해당 클래스의 객체를 생성하게 된다.
: 생성하는 순간 의존성이 생긴다.

의존성의 존재는 필수 불가결하다.

하지만 이 의존성을 최소한으로 줄이고 싶다.

의존성이 강하다면 뭐 하나 바꾸려하면
사용하는 모든 클래스에서 선언, 구현 모든 것들을 일일이 변경해야하기 때문이다.
(강한 결합 : 확장성 떨어짐, 유지보수 취약)

그저 나는 내 부분의 개발만 신경쓰며 유연하게 하고 싶은 것이다.

<문제점>

public class CMyAnimal {
  private Dog _dog;
  public CMyAnimal() {
    _dog = new Dog();
  }
}

생성자 내부에서 딱 Dog를 지정해 컴파일 단계에 결정해버렸다.
-> 강한 의존성
ex) Dog 가 짖는 것 만약 고양이를 넣으려면 고양이가 우는 것,
뭐 할때마다 각 객체당 모든 작업을 넣어줘야함.

2. Inversion Of Control (IOC)

위에서 클래스 내부에서 객체를 직접 생성했다.

이 방식을 바꿔보려고 한다.
즉, 생성자의 인자로 어떤 객체를 생성할지 정하는 것이다.

Callee내부에서 생성 -> Caller가 지정해줌.

객체의 제어 권한이 외부로 역전된 것이다.
= Inversion Of Control (IOC)

 

public class CMyAnimal {
  private Dog _dog;
  
  // 방법1. 생성자 : Constructor Injection
  public CMyAnimal(CDog dog) {
    _dog = dog;
  }
  
  // 방법2. 함수  : Method Injection
  public setDog(CDog dog) {
    _dog = dog;
  }
}

 

즉, 종속성 문제를 해결하기 위해 Ioc를 구현하고 싶은데,
다양한 방법 중 한가지가 DI 디자인 패턴인 것이다.


II. Interface

 

Interface의 필요성
: 동일한 성질의 그룹화
: 동일한 동작의 강제성
: 느슨한 결합

다양한 클래스 객체를 그룹화 하고 싶고,
하지만 비슷한 동작을 해야하고,
각 객체 자기 자신만 신경쓰고 싶은 것이다.

객체들의 관리를 하는 또 다른 객체가 필요하다.
-> 제 3자의 등장 = Interface 객체

각자 자신의 것만 개발해서 Interface에 등록하고
필요할때 인터페이스를 통째로 넘겨받고 선택하여 객체를 생성한다.
-> 인터페이스를 통해 객체를 주입받는다.

이 경우 내 객체, 네 객체의 관리 권한이 3자로 넘어갔다.

+) 이렇게 객체들을 관리하는 인터페이스를 Ioc Container라고 한다.

 


III. 구현

 

1. 간단한 구현

각 동물들은 IAnimal을 상속받고 IAnimal을 Container로 사용해보자.

public interface IAnimal {
  // 인터페이스 내 함수는 무조건 abstract
  void getSound();
}

public class CDog : IAnimal {
  public void getSound() => Console.WriteLine("Dog Sound");
}

public class CCat : IAnimal {
  public void getSound() => Console.WriteLine("Cat Sound");
}

// Callee
public class CMyAnimal {
  private IAnimal _IAnimal;
  public CMyAnimal(IAnimal Animal) {
    _IAnimal = Animal;
  }

public class CMain() {
  public void Main() {
    CMyAnimal myAnimal = new CMyAnimal(new CDog());
    myAnimal.getSound();
  }
}

Main에서 CMyAnimal을 생성하며 IAnimal 인터페이스를 생성하여 넘겨줬다.
- 인터페이스에 속한(상속받은) 객체를 인자로 넘겨주었다.
- 받은 Callee 부분에서는 이를 Interface 객체로 받게된다.
   -> 들어올때마다 Dog니 Cat이니 형을 맞춰주어 객체를 생성할 필요가 없음.

 

2. C# System 방식

C#에서 DI 패턴은 다음과 같은 구조를 갖게된다.

1. 내가 사용할 클래스 및 인터페이스를 다른 곳에 주입하기 위해서 Register를 통해 등록
2. 주입받을 곳에서 Provide로 Interface객체로 주입받음.

C#은 다음과 같이 제공되는 System Framework를 통해 DI를 구현할 수 있다.

+ Recent posts