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);
}
}
- 코드를 복사하여 붙여 넣으면 나중에 리팩터링하기가 어렵습니다. 점점 더 많은 개발자가 해당 블록을 복사하여 붙여 넣기 때문에 실제 블록이 무엇인지 알 수있는 사람이 줄어 듭니다.
- 더 근본적으로, 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 설정
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 설정
@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