개인 공부

의존성 주입 (DI, Dependency Injection ) / Dagger2

Machine_웅 2021. 12. 18. 21:43
728x90
반응형

1. 의존성 주입 이란? ( DI , Dependency Injection )

- 하나의 객체에 다른 객체의 의존성을 제공하는 기술 


1) 의존성 (Dependency)

- 객체 지향에서 두 클래스 간의 관계

2) 주입 ( Injection)

- 생성자나 메서드 등을 통해외부로부터 생성된 객체를 전달 받는 것.

 

* 의존성 주입 => 의존 관계에 있는 클래스의 객체를, 외부로 부터 생성하여 주입받는다.

부에서 객체를 관리하게 되는데 이를 IOC(inversion of Control, 제어의 역전)라 합니다. 

Note : IOC는 객체의 생성부터 생명주기 관리까지 컨테이너에 의해 제어 되는 것을 의미하고, 의존성 주입(DI)은 객체간의 의존성을 자기 자신이 아닌 외부에서 주입받는 개념입니다.

2. 의존성 주입의 장 ˙ 단점

1) 장점

- 의존성 주입은 인터페이스를 기반으로 설계되며, 코드를 유연하게 한다.

- 주입하는 코드만 따로 변경하기 쉬워 리펙토링이 수월하다.

- 단위테스트를 하기가 더욱 쉬워진다.

- 클래스간 결합도를 낮춘다.

 

2) 단점

- 간단한 프로그램을 만들 때는 번거롭다.

- 가독성이 떨어진다.

 

* 짧은 개발 기간과, 더이상 유지보수를 하지 않는 프로그램을 만드는 경우는 의존성 주입을 굳이 추천하지 않으나.

일반적 상용 어플리케이션을 만들고, 지속해서 유지보수를 해야한다면, 생산성이 향상된다.

3. Dagger2 란?

- 자바와 안드로이드를 위한 의존성 주입 프레임워크

 

특징

- 리플렉션을 사용하지 않는다.

- 컴파일 타임에 생성된다.

 

Dagger2의 장점

- 자원 공유의 단순화

- 복잡한 의존성을 단순하게 설정

- 유닛 테스트를 쉽게도와준다.

- 자동 코드 생성 ( 생성된 코드는 명확하고, 디버깅이 가능)

 

4. Dagger2 설정

- 링크:https://github.com/google/dagger

 

GitHub - google/dagger: A fast dependency injector for Android and Java.

A fast dependency injector for Android and Java. Contribute to google/dagger development by creating an account on GitHub.

github.com

 

5. Dagger2의 Annotation

 

1) @Module 과 @Provide

@Module은 클래스에만 붙이며 @Provide는 반드시 @Module클래스안에 선언된 메소드에만 붙입니다.

 

Module클래스는 의존성 주입에 필요한 객체들을 Provide메소드를 통해 관리 합니다.

Provide 메소드의 파라미터 또한 컴포넌트 구현체로부터 전달 받을 수 있습니다.

 

* 일반적인 사용 컨벤션 

일반적으로 Module클래스는 클래스이름 뒤에 Module을 붙이고,

Provide메소드명 앞에는 provide를 붙이는 것이 일반적인 컨벤션입니다.

@Module
public class AModule {
    @Provides
    AA provideAA(){ //AA 오브젝트를 컴포넌트에게 제공
        return new AA();
    }

    @Provides
    BB provideBB(AA aa){ //위에서 제공하는 AA를 컴포넌트로 부터 인자로 전달받아 BB를 제공
        return new BB(aa);
    }
}


@Module
public class BModule {
    @Provides
    String provideName(){
        return "Charles";
    }
}

2) @Nullable

- @Provides 메서드는 null을 반환하는 것을 기본적으로 제한한다.

- null을 인젝션 하고 싶다면 @Nullable 애노테이션을 이용해야합니다.

- @Provide 메소드와 객체를 주입받을 타입이 모두 쌍으로

  @Nullable 애노테이션이 붙어 있는 경우에만 null 주입을 허용하며,

  그 이외의 경우에는 컴파일 타임에 에러를 발생 시킵니다.

 

3) @Inject

@Inject는 필드, 생성자, 메소드에 붙여  컴포넌트로부터 객체를 주입받을 수 있게 합니다. 

* 실무에서는 필드 주입, 생성자 주입이 주로 사용 됩니다.

public class AA {
}

public class BB {
    public BB(AA aa){
    }
}

public class CC {
    AA aa;
    BB bb;
    @Inject
    public CC(AA aa, BB bb){//생성자에 주입하는 예제
        this.aa = aa;
        this.bb = bb;
    }
}
public class Main{ //필드에 주입하는 예제
    @Inject AA aa; 
    @Inject BB bb; 
    @Inject CC cc;
    ...
}

기본적으로 Dagger는 요청된 자료형에 맞게 Module로부터 인스턴스를 생성하여 주입을 받게 됩니다. 모든곳에서 @Inject가 동작하는것은 아닙니다. @Inject를 붙일 수 없는 경우는 다음과 같습니다.

  • 인터페이스는 생성자가 없으므로 불가능
  • 써드파티 라이브러리 등의 클래스는 참조가 불가능하여 애노테이션프로세싱이 안됨
  • 기타 등등

 

4)  @Component

@Component는 interface 또는 abstract 클래스에 붙일수 있습니다.

컴파일 타임에 애노테이션 프로세서에 의해 생성된 클래스는

접두어 ‘Dagger’와 @Component가 붙은 클래스이름이 합쳐진 형식의 이름을 갖습니다.

예를들면 @Component interface MyComponent{…}란 인터페이스가 있다면

DaggerMyComponent라는 클래스가 생성되게 됩니다.

 

@Component(modules = {AModule.class, BModule.class})
public interface MyComponent {
    //provision 메소드
    AA makeAA();

    //member-injection 메소드
    void inject(Main target);

}

Provision Method

프로비전 메소드에는 매개변수가 없고, 모듈이 제공하는 객체의 타입을 반환형으로 갖습니다. 생성된 컴포넌트 클래스에서 이 메소드를 이용하여 객체를 얻을 수 있습니다.

 

Member-Injection Method

의존성을 주입시킬 객체를 메소드의 파라미터로 넘기는 방법입니다. 멤버인젝션 메소드를 호출 하게 되면 타겟 클래스 내의 @Inject 필드에 객체를 주입받게 됩니다.

 

 

 

참고 : https://www.charlezz.com/?p=1259 

 

Dagger2를 알아보자 – 기본편 | 찰스의 안드로이드

Dagger2를 알아보자 - 기본편 (You're here) Dagger2를 알아보자 - Scope Dagger2를 알아보자 - Injection의 종류 Dagger2를 알아보자 - Qualifier Dagger2를 알아보자 - Binding Dagger2를 알아보자 - Multibinding Dagger2를 알아

www.charlezz.com

참고 : 아키텍처를 알아야 앱 개발이 보인다. ( 옥수환 지음 )

 

728x90
반응형

'개인 공부' 카테고리의 다른 글

CI ( Continuous Integration )  (0) 2022.03.26
MVVM?  (0) 2022.03.25
React Native 하면서 궁금했던거.  (0) 2021.08.08
여러가지 기타등등..  (0) 2021.02.15
Unity ?  (1) 2021.01.22