안드로이드

[Android] DI란?, Dagger2 사용법에 대해 알아보자

코딩하는후운 2022. 10. 27. 10:21
반응형

DI 기본 개념과 Dagger2사용 예제


DI란?
Dependency Injection의 약자로 의존성 주입을 의미합니다.
특정 객체의 인스턴스가 필요한 경우 이를 외부에서 생성하여 전달하는 기법.

Dagger란?
안드로이드에서 의존성 주입을 구현하기 위해 사용하는 라이브러리 입니다.

예제 - 햄버거 만들기
햄버거(Burger)는 밀빵(WheatBun)과 소고기 패티(BeefPatty)로 이루어져 있습니다.

햄버거
public class Burger{
  public WheatBun bun;
  public BeefPatty patty;

  public Burger(WheatBun bun, BeefPatty patty){
    this.bun = bun;
    this.patty = patty;
  }
}

밀빵
public class WheatBun{
  public String getBun(){
    return "밀빵";
  }
}

소고기 패티
public class BeefPatty{
  public String getBeefPatty(){
    return "소고기 패티";
  }
}



그러면 우리의 MainActivity에서 햄버거를 만드려면 어떻게 해야 할까요?

Burger burger;

onCreate(){
  WheatBun bun = new WheatBun();
  BeefPatty patty = new BeefPatty();

  burger = new Burger(bun, patty);

}



이렇게 new 오퍼레이터를 사용해서 밀빵과 소고기 패티를 가져와서 햄버거를 만듭니다.

MainActivity에서 인스턴스를 생성하는게 기존의 방식이었습니다.
여기에 의존성 주입을 사용하면 new 오퍼레이터 사용없이 외부에서 자동으로 객체를 생성해 줍니다.


Dagger2적용하기
0.App버전의 build.gradle에 라이브러리 추가하기

implementation "com.google.dagger:dagger:$daggerVersion"
implementation "com.google.dagger:dagger-android:$daggerVersion"
implementation "com.google.dagger:dagger-android-support:$daggerVersion"

kapt "com.google.dagger:dagger-android-processor:$daggerVersion"
kapt "com.google.dagger:dagger-compiler:$daggerVersion"




1.Module과 Component를 만들어야 합니다.
Module은 필요한 객체를 제공하는 역활을 합니다.

우리가 MainActivity에서 아래와 같이 객체를 생성했죠?

WheatBun bun = new WheatBun();
BeefPatty patty = new BeefPatty();

Burger burger = new Burger(bun, patty);



이걸 Module이 해줍니다.

@Module
public class BurgerModule{
  @Provides
  Burger provideBurger(WheatBun bun, BeefPatty patty){
    return new Burger(bun, patty);
  }

  @Provides
  WheatBun provideBun(){
    return new WheatBun();
  }

  @Provides
  BeefPatty providePatty(){
    return new BeefPatty();
  }
}



생성할 객체를 @Provides어노테이션을 사용해서 생성해 줍니다.

Component는 모듈에서 제공받은 객체를 조합하여 필요한 곳에 주입하는 역활을 합니다.

@Component(modules = BurgerModule.class)
public interface BurgerComponent{
  void inject(MainActivity activity);
}



@Component어노테이션을 통해 BurgerModule.class를 가져왔습니다. 이를 inject() 함수를 통해 MainActivity에
주입했습니다.(void inect()의 함수 명은 정해진 값이 아닌 임의의 함수명을 정해주시면 됩니다.)


2.MainActivity에서 사용해보기
1번 작업을 한 후 프로젝트를 빌드 해주시면 Dagger + {ComponentName}파일이 자동 생성됩니다.
(여기서는 DaggerBurgerComponent가 생성됩니다. 이렇게 컴파일 단계에서 의존성을 체크할 수 있어 앱의 안정성을 높여줄 수 있습니다.)

BurgerComponent component = DaggerBurgerComponent.builder()
  .burgerModule(new BurgerModule())
  .build();

component.inject(this);



위와 같이 new 오퍼레이터 사용 없이 위와 같은 코드로 burger객체를 외부에서 생성하여 가져올 수 있습니다.

간단히 공급하는놈(Module)과 주입받는 놈(Inject)
그리고 이 사이를 연결해주는 놈(Component)로 이해하시면 됩니다.


Module
Module에서 공급할 객체를 생성합니다(예제에서는 햄버거, 밀빵, 소고피 패티를 생성했습니다.)

Component
component에서는 Module을 불러오고 어디로 주입할 지를 정합니다.

Inject
@Inject어노테이션을 통해 주입받는 놈을 가져옵니다.




2개의 모듈 가져오기
Component

@Component(modules = {ChefModule.class, KitchenModule.class})
public interface MyComponent{
  void inject(MainActivity activity);
}






Dagger2를 사용하여 SharedPref를 다뤄보자.
기존

private SharedPreferences sharedPreferences;

sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
sharedPreferences.edit().putString("status", "success").applay();



이를 Dagger2를 사용한 예제로 변경해 보겠습니다.

1.ApplicationModule

@Module
public class ApplicationModule{
  private Application mApp;

  ApplicationModule(Application app){
    mApp = app;
  }

  @Provides
  @singleton
  SharedPreferences provideSharedPrefs(){
    return PreferenceManager.getDefaultSharedPreferences(mApp);
  }
}



이와 같이 모듈을 만들어 줍니다. mApp변수를 가져오기 위해 ApplicationModule(application app)라는 생성자를 만들었습니다.
또한 SharedPreferences는 같은 객체 1개만 있으면 되기 때문에 @singletone어노테이션을 설정했습니다.


2.ApplicationComponent

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent{
  void inject(MainActivity activity);
}


메인액티비티에 sharedPref를 주입할 예정입니다.


3.DemoApplication

public class DemoApplication extends Application{
  private ApplicationComponent mConpoment;

  @Override
  public void onCreate(){
    super.onCreate();

    mComponent = DaggerApplicationComponent.builder()
                  .applicationModule(new ApplicationModule(this))
                  .build();
  }

  public ApplicationComponent getComponent(){
    return mComponent;
  }
}



Application단계에서 component를 최초 초기화 해줍니다.
이렇게 해줌으로써 Module에서 제공하는 SharedPref를 최초 한ㅂ너 초기화 해줄 수 있습니다.

_MainActivity

@Inject
SharedPreferences mSharedPrefs;

  ((DemoApplication) getApplication())
          .getComponent()
          .inject(this);

  mSharedPrefs.edit()
      .putString("status", "success!")
      .apply();

 

 

참조 :

https://black-jin0427.tistory.com/104?category=727620 

 

[Android, Dagger2] DI 기본 개념과 Dagger2 사용 예제 - 놈!놈!놈!

안드로이드 DI 와 Dagger2 에 관한 포스팅을 해보겠습니다. 설명은 굉장히 짧게! 이해는 아주 잘 되게! DI 란? DI 는 Dependency Injection 의 약자로 의존성 주입을 의미합니다. 특정 객체의 인스턴스가 필

black-jin0427.tistory.com

 

반응형