Dagger2
Dagger
Dagger가 무엇인지는 구글링하면 다 나온다. 많은 개발자들이 쓰고 있고, 구글샘플에도 필수적으로 사용되고 있다. 나도 얼마 전부터 이를 사용하고 있다. 사용하면 작성 클래스는 늘지만 좀 있어(?) 보인다. 그리고 뭔가 편하다는 것을 조금 느낀다. 각종 문서를 훑어봐도 원리를 제대로 이해하기는 힘들다. 여유를 갖자.(유연성을 갖자)
@Inject
구글링 하면 @Inject가 뭔지 알 수 있다. class상에서 @Inject의 순서는 중요하다. 초기화(객체 생성)는 선언한 순서대로다.
@Inject Adapter adapter;
@Inject Presenter presenter;
.
.
@Inject(2)
클래스 생성자에 @Inject 해주면, Dagger 모듈에서 자동으로 생성해준다.
public class SchedulersFacade {
@Inject
public SchedulersFacade() {}
}
아래와 같이 모듈을 생성할때, SchedulersFacade 매개변수를 선언해 준 것 만으로 객체가 생성되어 넘어온다.
@Module public class SearchActivityModule {
@Singleton @Provides
public SearchViewPresenter provideSearchViewPresenter(SearchViewPresenter.View view,
SchedulersFacade schedulers) {
return new SearchViewPresenterImpl(view, schedulers);
}
}
@Singleton
@Singleton은 Dagger에서 제공하는 Annotation이 아니다.
@Singleton을 사용하지 않았을 때, Dagger가 주입한 객체를 재사용하는 것이 조금 부담이었다. 가령, @Inject Adapter adapter 이후 Module에서 재사용 할 때, View에서 주입한 Adapter를 다시 가져오는 방식이었다.
@Inject @Getter CustomAdapter adapter;
@Inject Presenter presenter;
그러나 Module에서 @Singleton을 사용하면 그럴 필요가 없다. Singleton이기 때문에..
주의할 점이 있다. Module에서 사용하기 전, Component에서 반드시 선언해 주어야 한다. 안해주면 에러를 뿜는다.
// Component, Module, Provider 클리스 구조일 경우
@Singleton
@Subcomponent(modules = { EmpListFragmentModule.class }) public interface EmpListFragmentComponent
extends AndroidInjector<EmpListFragment>
@ContributesAndroidInjector
Dagger에서 이것을 사용하면, Component, Provider등의 클래스를 없앨 수 있다. 자동으로 만들어지는 것 같다.
대신, @Provides를 사용하여 메서드를 선언하고 구현하려면 반드시 static을 사용해야 한다.
@Module public abstract class TeamReportActivityModule {
@ContributesAndroidInjector(modules = TeamReportDialogModule.class)
abstract TeamReportDialog bindTeamReportDialog();
@Provides static TeamReportPresenter.View provideTeamReportView(TeamReportActivity TeamReportActivity) {
return TeamReportActivity;
}
....
A is bound multiple times
Dagger에서 A 객체를 너무 많이 사용했다는 의미다. A를 B(또는 'B extends A')다른 클래스 또는 인터페이스로 바꾸어 사용하면 문제 없이 동작한다. 좀 더 명확하게 사용하라는 메시지 인것 같다.