Android

Dagger2 tutorial

aucd29 2018. 6. 27. 14:16
느즈막히 대거를 보고 있는데 =_ = 이거 spring 에 @AutoWired 처럼 알아서 되야지 내가 왜 다 설정해야 되냐? 라는 생각이 먼저 듬 =_ = ㅋ
Square 에서 구글로 넘어갔다고 하니 일해라 구글!!!

공식 가이드
    - https://google.github.io/dagger/users-guide

기본 개념 잡기 좋은 사이트
    - http://www.vogella.com/tutorials/Dagger/article.html#introduction-to-the-concept-of-dependency-injection

구글 샘플
    - https://github.com/googlesamples/android-architecture/blob/todo-mvp-dagger/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/ToDoApplication.java

소개 ppt
    - https://speakerdeck.com/jakewharton/dependency-injection-with-dagger-2-devoxx-2014

기타 예제
    - https://github.com/jshvarts/DaggerAndroidMVVM

gradle 선언
    ext.dagger         = '2.14.1'    // 2.16 까지 나옴
    
    // dagger 2
    implementation "com.google.dagger:dagger:$dagger"
    annotationProcessor "com.google.dagger:dagger-compiler:$dagger"
    // dagger 2 android
    implementation "com.google.dagger:dagger-android-support:$dagger"
    annotationProcessor "com.google.dagger:dagger-android-processor:$dagger"
    // implementation "com.google.dagger:dagger-android-support:$dagger"

일단 정확하진 않고 아리까리 하지만 =_ = 오늘 오전에 시간 내서 봐본 결과 Application 에서는 Activity 에 대한 설정, Activity 에서는 Fragment 에 대한 설정을 할수 있는데 이걸
DaggerApplication, DaggerAppCompatActivity 식으로 미리 구성해둔 라이브러리가 존재하니 이를 이용하면 소스 거저 먹을 수 있음..

어노테이션들의 의미
@Module + @Provides : mechanism for providing dependencies.
@Inject : mechanism for requesting dependencies.
@Component : bridge between modules and injections

Application 에서는 Component 를
Component 에서는 Module 들을
Module 에서는 Activity 를 선언

하고 Application 에서 inject(this) 하면 Activity 에서 나 Fragment 에서 @Inject 로 선언한 멤버 변수에 injection 이 가능 한데
이때 대상 클래스의 생성자에 @Inject 를 선언해두어야 함
기본 룰은 이런 듯

간단 예제
    - https://gist.github.com/aucd29/46f3931f5c9329a5aeff51555f02ac3d

Dagger 2 how to perform constructor injection
    - https://stackoverflow.com/questions/45192878/dagger-2-how-to-perform-constructor-injection

Inject viewmodel (음... =_ = view model factory 를 새로 만드는거 외에 방법이 없나? 먼가 지저분한데..)
    - https://proandroiddev.com/mvvm-architecture-viewmodel-and-livedata-part-2-di-1a6b1f96d84b
    - https://blog.mindorks.com/the-new-dagger-2-android-injector-cbe7d55afa6a
    - 가령 view model provider 를 굳이 google 걸 써야 되나? 굳이 그 틀이 아니여도 괜찮을 거 같은데? dagger 에서 viewmodel 를 지원해줘야 하는거 아닌가 싶은데 ?

View 내에서 inject 은 Application 에 선언해두었던 AppComponent 에 원하는 View 를 직접 선언해서 할 수 있다.
가령 FrameLayout 를 상속한 Card 라는 View 클래스내에서 inject 를 원하면

public interface AppComponent {
    void inject(Card view);
}
식으로 선언 해두고 view 를 생성 시 inject 를 요청해서 사용할 수 있다.

https://github.com/digitalbuddha/DaggerAndroidViewInjectior

어!! Dagger2MultidexApplication 없다.. =_ =

@ContributesAndroidInjector
    - https://proandroiddev.com/dagger-2-annotations-binds-contributesandroidinjector-a09e6a57758f

New Android Injector with Dagger 2 — part 2
    - https://medium.com/@iammert/new-android-injector-with-dagger-2-part-2-4af05fd783d0

@Named 를 이용해서 Inject 시 옵션이 다른 객체를 얻을 수 있음

@Provides @Named("cached") @Singleton
OkHttpClient provideOkHttpClient(Cache cache) {
    OkHttpClient client = new OkHttpClient();
    client.setCache(cache);
    return client;
}

@Provides @Named("non_cached") @Singleton
OkHttpClient provideOkHttpClient() {
    OkHttpClient client = new OkHttpClient();
    return client;
}

@Inject @Named("cached") OkHttpClient client;
@Inject @Named("non_cached") OkHttpClient client2;



External links
https://google.github.io/dagger/android
http://drcarter.tistory.com/169
http://imcreator.tistory.com/106
https://antonioleiva.com/dependency-injection-android-dagger-part-1/
https://github.com/ZeroBrain/AndroidSamples
https://proandroiddev.com/how-to-dagger-2-with-android-part-1-18b5b941453f