Transcript
Page 1: Dagger 2 - Injeção de Dependência

Dagger 2INJEÇÃO DE DEPENDÊNCIA

Page 2: Dagger 2 - Injeção de Dependência

Injecão de Dependência Dependência é qualquer objeto necessário

para o funcionamento de uma classe;

Desacoplamento entre classes de alto e baixo nível;

Inexistente, manual ou automática.

Page 3: Dagger 2 - Injeção de Dependência

public class ClassA {

private ClassB mClassB; public ClassA() { mClassB = new ClassB(); }}

Page 4: Dagger 2 - Injeção de Dependência

public class ClassA {

private ClassB mClassB; public ClassA() { mClassB = new ClassB(new ClassC()); }}

Page 5: Dagger 2 - Injeção de Dependência

public class ClassA {

private ClassB mClassB; public ClassA(ClassB classB) { mClassB = classB; }}

Page 6: Dagger 2 - Injeção de Dependência

Bibliotecas Guice

Dagger (v1)

Dagger 2

...

Page 7: Dagger 2 - Injeção de Dependência

Funcionamento@Bind(R.id.home_iv) ImageView mImageView;

ButterKnife.bind(this, view);

view mImageView

findViewbyId

@Bind

mImageView = (ImageView)view.findViewbyId(R.id.home_iv);

Page 8: Dagger 2 - Injeção de Dependência

Funcionamento

Component Object“findObjectOfTypeX”

@Inject

Module

Page 9: Dagger 2 - Injeção de Dependência

Exemplo

Retrofit

bit.ly/di-android-meetup

Page 10: Dagger 2 - Injeção de Dependência

Retrofit Servicepublic class GitHubApi {

public static final int CACHE_SIZE = 5 * 1024 * 1024;

public static <S> S createService(Class<S> serviceClass, Context context) {

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); final Gson gson = gsonBuilder.create();

OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(interceptor) .cache(new Cache(context.getCacheDir(), CACHE_SIZE)) .readTimeout(30, TimeUnit.SECONDS) .connectTimeout(30, TimeUnit.SECONDS) .build();

Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson))

.baseUrl(BuildConfig.API_URL)

.client(client)

.build();

return retrofit.create(serviceClass); }}

Page 11: Dagger 2 - Injeção de Dependência

UserModelpublic class GitHubUserModel {

private final GitHubService mService;

public GitHubUserModel(Context context) { mService = GitHubApi.createService(GitHubService.class, context); }

public Call<List<GitHubUser>> fetchUsers(int page) { return mService.getUsers(page); }

...

}

GitHubUserModel userModel = new GitHubUserModel(getActivity().getApplicationContext());mActionInteractor = new UsersListPresenter(this, userModel);mActionInteractor.loadUsersList(false);

Page 12: Dagger 2 - Injeção de Dependência

Introduzindo Dagger

Page 13: Dagger 2 - Injeção de Dependência

Dagger API @Module + @Provides

Mecanismo para prover dependências

@Inject Mecanismo para requisitar dependências

@Component Ligação entre módulos e injeções

Page 14: Dagger 2 - Injeção de Dependência

DaggerProject/build.gradle

buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.5.0' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8’ }}

App/build.gradle

apply plugin: 'com.neenbedankt.android-apt'

compile 'com.google.dagger:dagger:2.0.2'apt 'com.google.dagger:dagger-compiler:2.0.2'provided 'org.glassfish:javax.annotation:10.0-b28'

Page 15: Dagger 2 - Injeção de Dependência

@Modulepublic class NetworkModule {

public static final int CACHE_SIZE = 5 * 1024 * 1024;

@Provides public Retrofit provideRetrofit(Gson gson, OkHttpClient client) { return new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl(BuildConfig.API_URL) .client(client) .build(); } @Provides public OkHttpClient provideHttpClient(HttpLoggingInterceptor interceptor, Cache cache) { return new OkHttpClient.Builder() .addInterceptor(interceptor) .cache(cache) .connectTimeout(60, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) .build(); }

@Provides public Cache provideCache(Application application) { return new Cache(application.getCacheDir(), CACHE_SIZE); }

@Provides public HttpLoggingInterceptor provideHttpInterceptor() { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); return interceptor; }

@Provides public Gson provideHttpGson() { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); return gsonBuilder.create(); }}

Page 16: Dagger 2 - Injeção de Dependência

@Modulepublic class GitHubModule {

public interface GitHubService {

@GET("/users") @Headers("Authorization: token " + BuildConfig.GITHUB_TOKEN) Call<List<GitHubUser>> getUsers();

@GET("/users/{login}") @Headers("Authorization: token " + BuildConfig.GITHUB_TOKEN) Call<GitHubUser> getUser(@Path("login") String login);

@GET("/users") @Headers("Authorization: token " + BuildConfig.GITHUB_TOKEN) Call<List<GitHubUser>> getUsers(@Query("since") int page); }

@Provides public GitHubService provideGitHubService(Retrofit retrofit) { return retrofit.create(GitHubService.class); }}

Page 17: Dagger 2 - Injeção de Dependência

@Modulepublic class AppModule {

private final Context mApplicationContext;

public AppModule(Context applicationContext) { mApplicationContext = applicationContext; }

@Provides @PerApp public Context provideApplicationContext() { return mApplicationContext; }}

Page 18: Dagger 2 - Injeção de Dependência

@Component(modules = {AppModule.class, GitHubModule.class, NetworkModule.class})public interface AppComponent {

void inject(UsersListFragment fragment);}

DepencyInjectionApplication.java

@NonNullprotected DaggerAppComponent.Builder prepareAppComponent() { return DaggerAppComponent.builder() .networkModule(new NetworkModule()) .gitHubModule(new GitHubModule()) .appModule(new AppModule(this));}

Page 19: Dagger 2 - Injeção de Dependência

GitHubUserModel.java

public class GitHubUserModel {

private final GitHubModule.GitHubService mService;

@Inject public GitHubUserModel(GitHubModule.GitHubService service) { mService = service; } ...}

UsersListFragment.java@Inject public GitHubUserModel mUserModel;

@Overrideprotected void onCreate() { DepencyInjectionApplication.getAppComponent(getActivity()).inject(this);}

@Overrideprotected void onResume() { mActionInteractor = new UsersListPresenter(this, mUserModel); mActionInteractor.loadUsersList(false);}

Page 20: Dagger 2 - Injeção de Dependência

GitHubUserModel

Retrofit

OkHttpClient

Gson

NetworkModule#provideRetrofit

NetworkModule#provideHttpClient

NetworkModule#provideGson

GitHubService GitHubModule#provideGitHubService

Page 21: Dagger 2 - Injeção de Dependência

Component Dependency

Page 22: Dagger 2 - Injeção de Dependência

@Component(modules={AppModule.class, NetworkModule.class})public interface NetComponent {

Retrofit retrofit();}

@Component(dependencies = NetComponent.class, modules = GitHubModule.class)public interface AppComponent {

void inject(UsersListFragment fragment);}

public class DepencyInjectionApplication extends Application {

private AppComponent mAppComponent;private NetComponent mNetComponent;

private void setupDaggerAppComponent() { mNetComponent = DaggerNetComponent.builder() .appModule(new AppModule(this)) // .networkModule(new NetworkModule()) is free .build();

mAppComponent = DaggerAppComponent.builder() // .gitHubModule(new GitHubModule()) is free .netComponent(mNetComponent) .build();}

}

Page 23: Dagger 2 - Injeção de Dependência

Subcomponent

Page 24: Dagger 2 - Injeção de Dependência

@Subcomponent(modules = GitHubModule.class)public interface GitHubComponent {

void inject(UsersListFragment fragment);}

@Component(modules = {NetworkModule.class, AppModule.class})public interface AppComponent {

Application getApplication();

GitHubComponent plus(GitHubModule gitHubModule);}

DepencyInjectionApplication.javaprivate void setupDaggerAppComponent() { mAppComponent = DaggerAppComponent.builder() .appModule(new AppModule(this)) .build();}

UsersListFragment.java@Overrideprotected void onCreate() { DepencyInjectionApplication.getAppComponent(getActivity()) .plus(new GitHubModule()) .inject(this);}

@Overrideprotected void onResume() { mActionInteractor = new UsersListPresenter(this, mUserModel); mActionInteractor.loadUsersList(false);}

Page 25: Dagger 2 - Injeção de Dependência

Scopes Determinam a intenção de duração de ciclo de vida

de um component;

@Singleton é o único suportado out-of-the-box; Deve ser usado no nível de aplicação

Custom scopes permitem maior flexibilidade, mas cabe ao programador respeitar o ciclo de vida.

Page 26: Dagger 2 - Injeção de Dependência

@Scope@Retention(RetentionPolicy.RUNTIME)public @interface PerActivity {}

@Modulepublic class MyActivityModule {

@PerActivity @Named("ActivityScope") @Provides StringBuilder provideStringBuilderActivityScope() { return new StringBuilder("Activity"); }

@Named("Unscoped") @Provides StringBuilder provideStringBuilderUnscoped() { return new StringBuilder("Unscoped"); }}

Page 27: Dagger 2 - Injeção de Dependência

public class MyActivity {

@Inject @Named("ActivityScope") StringBuilder activityScope1;

@Inject @Named("ActivityScope") StringBuilder activityScope2;

@Inject @Named("Unscoped") StringBuilder unscoped1;

@Inject @Named("Unscoped") StringBuilder unscoped2;

public void onCreate() {

activityScope1.append("123"); activityScope1.toString(); // output: "Activity123"

activityScope2.append("456"); activityScope2.toString(); // output: "Activity123456"

unscoped1.append("123"); unscoped1.toString(); // output: "Unscoped123"

unscoped2.append("456"); unscoped2.toString(); // output: "Unscoped456"

}}

Page 28: Dagger 2 - Injeção de Dependência

Bonus Lazy; Inicialização de Map e Set; Producer assíncrono;

Page 29: Dagger 2 - Injeção de Dependência

Conclusão Fácil acesso à variáveis compartilhadas;

Desacoplamento de dependências complexas;

Controle de ciclo de vida;

Performance.

Page 30: Dagger 2 - Injeção de Dependência

Dúvidas?edson-menegatti-87898718

3dm1edson.menegatti.7

Page 31: Dagger 2 - Injeção de Dependência

Referênciashttps://www.youtube.com/watch?v=oK_XtfXPkqwhttps://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2https://www.parleys.com/tutorial/5471cdd1e4b065ebcfa1d557/https://blog.gouline.net/2015/05/04/dagger-2-even-sharper-less-square/https://www.youtube.com/watch?v=SKFB8u0-VA0


Recommended