Contenu connexe Similaire à Dagger 2 - Injeção de Dependência (20) Dagger 2 - Injeção de Dependência2. 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.
4. public class ClassA {
private ClassB mClassB;
public ClassA() {
mClassB = new ClassB(new ClassC());
}
}
5. public class ClassA {
private ClassB mClassB;
public ClassA(ClassB classB) {
mClassB = classB;
}
}
10. Retrofit Service
public 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);
}
}
11. UserModel
public 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);
13. Dagger API
@Module + @Provides
Mecanismo para prover dependências
@Inject
Mecanismo para requisitar dependências
@Component
Ligação entre módulos e injeções
15. @Module
public 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();
}
}
16. @Module
public 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);
}
}
17. @Module
public class AppModule {
private final Context mApplicationContext;
public AppModule(Context applicationContext) {
mApplicationContext = applicationContext;
}
@Provides
@PerApp
public Context provideApplicationContext() {
return mApplicationContext;
}
}
18. @Component(modules = {AppModule.class, GitHubModule.class, NetworkModule.class})
public interface AppComponent {
void inject(UsersListFragment fragment);
}
DepencyInjectionApplication.java
@NonNull
protected DaggerAppComponent.Builder prepareAppComponent() {
return DaggerAppComponent.builder()
.networkModule(new NetworkModule())
.gitHubModule(new GitHubModule())
.appModule(new AppModule(this));
}
19. GitHubUserModel.java
public class GitHubUserModel {
private final GitHubModule.GitHubService mService;
@Inject
public GitHubUserModel(GitHubModule.GitHubService service) {
mService = service;
}
...
}
UsersListFragment.java
@Inject public GitHubUserModel mUserModel;
@Override
protected void onCreate() {
DepencyInjectionApplication.getAppComponent(getActivity()).inject(this);
}
@Override
protected void onResume() {
mActionInteractor = new UsersListPresenter(this, mUserModel);
mActionInteractor.loadUsersList(false);
}
22. @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();
}
}
24. @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.java
private void setupDaggerAppComponent() {
mAppComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
}
UsersListFragment.java
@Override
protected void onCreate() {
DepencyInjectionApplication.getAppComponent(getActivity())
.plus(new GitHubModule())
.inject(this);
}
@Override
protected void onResume() {
mActionInteractor = new UsersListPresenter(this, mUserModel);
mActionInteractor.loadUsersList(false);
}
25. 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.
26. @Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity {}
@Module
public class MyActivityModule {
@PerActivity
@Named("ActivityScope") @Provides
StringBuilder provideStringBuilderActivityScope() {
return new StringBuilder("Activity");
}
@Named("Unscoped") @Provides
StringBuilder provideStringBuilderUnscoped() {
return new StringBuilder("Unscoped");
}
}
27. 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"
}
}
29. Conclusão
Fácil acesso à variáveis compartilhadas;
Desacoplamento de dependências complexas;
Controle de ciclo de vida;
Performance.