본문
170609 (금) - DI with Dagger2
DI with Dagger2
http://frogermcs.github.io/dependency-injection-with-dagger-2-the-api/
- source trace가 된다는 점이 Dagger2의 가장 큰 장점
- less dynamic 하면서 사용자가 hand-written code 한것과 비슷한 level 로 코드를 생성한다.
- Dagger2 API
public @interface Compnent {
Class<?>[] modules() default {};
Class<?>[] dependencies() default {};
}
public @interface Subcomponent {
Class<?>[] modules() default {};
}
public @interface Module {
Class<?>[] includes() default {};
}
public @interface Provides {}
public @interface MapKey {
boolean unwrapValue() default true;
}
public interface Lazy<T> {
T get();
}
- JSR-330 (Standard for DI in Java)
public @interface Inject {}
public @interface Scope {}
public @interface Qualifier {}
- @Inject
- JSR-330 standard
- 3 difference ways to provide dependencies
- constructor
- 둘 이상의 생성자에 @Inject 하지는 못한다.
public class LoginActivityPresenter { private LoginActivity loginActivity; private UserDataStore userDataStore; private UserManager userManager; @Inject public LoginActivityPresenter(LoginActivity loginActivity, UserDataStore userDataStore, UserManager userManager) { this.loginActivity = loginActivity; this.userDataStore = userDataStore; this.userManager = userManager; } }
- Field
- private 사용 불가능
public class SplashActivity extends AppCompatActivity { @Inject LoginActivityPresenter presenter; @Inject AnalyticsManager analyticsManager; @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); getAppComponent().inject(this); } }
- Method
public class LoginActivityPresenter { private LoginActivity loginActivity; @Inject public LoginActivityPresenter(LoginActivity loginActivity) { this.loginActivity = loginActivity; } @Inject public void enableWatches(Watches watches) { watches.register(this); //Watches instance required fully constructed LoginActivityPresenter } }
- @Module
- Dagger2 API
- 필요한 object가 생성되는 위치를 알 수 있다.
@Module public class GithubApiModule { @Provides @Singleton OkHttpClient provideOkHttpClient() { OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setConnectTimeout(60 * 1000, TimeUnit.MILLISECONDS); okHttpClient.setReadTimeout(60 * 1000, TimeUnit.MILLISECONDS); return okHttpClient; } @Provides @Singleton RestAdapter provideRestAdapter(Application application, OkHttpClient okHttpClient) { RestAdapter.Builder builder = new RestAdapter.Builder(); builder.setClient(new OkClient(okHttpClient)) .setEndpoint(application.getString(R.string.endpoint)); return builder.build(); } }
- @Provides
- return dependencies
- @Component
- build interface which wires everything together.
- @Module과 @Inject의 브릿지 역할
- @Component는 다른 compenent를 depend 가능
@Singleton @Component(modules = {AppModule.class, GithubApiModule.class}) public interface AppComponent { void inject(GithubClientApplication githubClientApplication); Application getApplication(); AnalyticsManager getAnalyticsManager(); UserManager getUserManager(); }
@ActivityScope @Component(modules = SplashActivityModule.class, dependencies = AppComponent.class) public interface SplashActivityComponent { SplashActivity inject(SplashActivity splashActivity); SplashActivityPresenter presenter(); }
- @Scope
- JSR-330 standard
- custom scope annotation define
- validation process에 사용되어 가능한 빨리 그래프 구조 문제를 catch하는데 도움이 된다.
- object의 single instance를 유지
@Scope public @interface ActivityScope { }
- @MapKey
- dependencies collection
- String and Enums 만 지원
@MapKey(unwrapValue = true) @interface TestKey { String value(); }
@Provides(type = Type.MAP) @TestKey("foo") String provideFooKey() { return "foo value"; } @Provides(type = Type.MAP) @TestKey("bar") String provideBarKey() { return "bar value"; }
@Inject Map<String, String> map; map.toString() // => „{foo=foo value, bar=bar value}”
@Qualifier
- 동일한 interface를 가진 dependencies 에 대해 "tag"를 생성
@Provides @Singleton @GithubRestAdapter //Qualifier RestAdapter provideRestAdapter() { return new RestAdapter.Builder() .setEndpoint("https://api.github.com") .build(); } @Provides @Singleton @FacebookRestAdapter //Qualifier RestAdapter provideRestAdapter() { return new RestAdapter.Builder() .setEndpoint("https://api.facebook.com") .build(); }
@Inject @GithubRestAdapter RestAdapter githubRestAdapter; @Inject @FacebookRestAdapter RestAdapter facebookRestAdapter;
'Mobile > DI' 카테고리의 다른 글
170609(금) - DI with Dagger2 (0) | 2017.06.09 |
---|---|
170609(금) - DI with Dagger2 (0) | 2017.06.09 |
170608(목) - DI with Dagger2 (0) | 2017.06.08 |
170608(목) - DI with Dagger2 (0) | 2017.06.08 |
170608(목) - DI with Dagger2 (0) | 2017.06.08 |
댓글