Dagger2

Dagger2는 자바와 안드로이드를위한 완전히 정적 인 컴파일 타임 의존성 주입 프레임 워크입니다. 이것은 구글에 의해서 만들어졌습니다.




Dagger2 Android

안드로이드 용으로 작성된 코드는 자바 소스이지만, 종종 스타일 측면에서 상당히 다르다. 일반적으로 이러한 차이점 은 모바일 플랫폼 의 고유 한 성능 고려 사항을 수용 하기 위해 존재합니다 .




기존Dagger의 문제

public class FrombulationActivity extends Activity {
  @Inject Frombulator frombulator;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ((SomeApplicationBaseType) getContext().getApplicationContext())
        .getApplicationComponent()
        .newActivityComponentBuilder()
        .activity(this)
        .build()
        .inject(this);
  }
}

  1. 코드를 복사하여 붙여 넣으면 나중에 리팩터링하기가 어렵습니다. 점점 더 많은 개발자가 해당 블록을 복사하여 붙여 넣기 때문에 실제 블록이 무엇인지 알 수있는 사람이 줄어 듭니다.
  2. 더 근본적으로, injector에 대해 알기 위해서는 injection ( )을 요구하는 타입이 필요합니다 . 비록 이것이 구체적인 타입 대신에 인터페이스를 통해 이루어 지더라도, 의존성 주입의 핵심 원칙을 깨뜨립니다. 즉 클래스는 그것이 주입되는 방법에 대해 아무것도 알지 못해야 합니다.

Usage

Google Support Library를 사용하신다면 'com.google.dagger:dagger-android-support:2.11'를 추가해주시면됩니다.

gradle은 annotationProcessor를 지원하는 3.0 이상버전으로 Upgrade

이하로 사용하시고 있다면 android-apt를 사용하시면 됩니다.


dependencies {
    compile 'com.google.dagger:dagger-android:2.11'
    compile 'com.google.dagger:dagger-android-support:2.11' // if you use the support libraries
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.11'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
}






Application 설정

HasActivityinjector를 implement 한후에 activityInjector를 override 합니다.
class UILApplication : Application() , HasActivityInjector {
    @Inject lateinit var activityInjector: DispatchingAndroidInjector<Activity>

    override fun activityInjector(): AndroidInjector<Activity> {
        return activityInjector
    }

    override fun onCreate() {
        super.onCreate()
        DaggerAppComponent.builder()
                .application(this)
                .build()
                .inject(this)
    }
}





AppComponent 설정

AppCompoent에서 AppModule 뿐아니라 ActivityBuilder,AndroidInjectionModule을 Component Annotation으로 연결합니다.

Dagger2버전에서의 Activity component들이 ActivityBuilder로 대체되었다고 생각하시면 됩니다.


@Singleton
@Component(modules = arrayOf(
        AndroidInjectionModule::class,
        AppModule::class,
        ActivitiesBuilder::class
))
interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder
        fun build(): AppComponent
    }


    fun inject(app: UILApplication)
}


ActivitiesBuilder 설정

각 ActivityModule을 설정합니다. 저는 Splash화면의 ActivityModule만 매칭하였습니다.
@Module
abstract class ActivitiesBuilder {

    @ContributesAndroidInjector(modules = arrayOf(SplashActivityModule::class))
    internal abstract fun bindMainActivity(): SplashActivity
}





AppModule 설정

Application에서 공통으로 사용하는 객체를 Provider합니다.

@Module
class AppModule {

    @Provides
    @Singleton
    fun provideContext(application: Application): Context {
        return application
    }


    @Provides
    @Singleton
    fun appExcuter(): AppExecutors{
        return AppExecutors()
    }

}



Activity Injection주입

해당 Activity에서 직접 Inject해도 되지만 BaseActivity에서 공통으로 Inject하게되면 별도로 Child Activity inject에 대한 코드를 적어주지 않아도 됩니다.

class BaseActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
    }
}




[Reference]

https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2

https://google.github.io/dagger/android.html





+ Recent posts