본문

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

공유

댓글