- Hugo,
Bonjour,
Contexte
Je souhaitais mettre en place une architecture mvp pour une application Android. Pour cela, je comptais utiliser une libraire d'injection de dépendances pour injecter ma views
dans mon presenter. Pour cela, j'ai créé un module, un component et une annotation FragmentScoped
.
Dans mon presenter
, j'ai eu besoin de la librairie Retrofit pour faire des requêtes HTTP (normalement ce code devrait être dans le model, mais pour la simplicité, j'ai fait comme ça, temporairement).
Donc mon code ressemble à ça pour l'instant:
La partie Retrofit:
Module :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | @Module public class NetModule { String mBaseUrl; // Constructor needs one parameter to instantiate. public NetModule(String baseUrl) { this.mBaseUrl = baseUrl; } // Dagger will only look for methods annotated with @Provides @Provides @Singleton // Application reference must come from org.esiag.isinthefuture.crmandroid.dagger.module.AppModule.class SharedPreferences providesSharedPreferences(Application application) { return PreferenceManager.getDefaultSharedPreferences(application); } @Provides @Singleton Cache provideOkHttpCache(Application application) { int cacheSize = 10 * 1024 * 1024; // 10 MiB Cache cache = new Cache(application.getCacheDir(), cacheSize); return cache; } @Provides @Singleton Gson provideGson() { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); return gsonBuilder.create(); } @Provides @Singleton OkHttpClient provideOkHttpClient(Cache cache) { OkHttpClient client = new OkHttpClient(); client.setCache(cache); return client; } @Provides @Singleton Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) { Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl(mBaseUrl) .client(okHttpClient) .build(); return retrofit; } } |
Le component :
1 2 3 4 5 | @Singleton @Component(modules={AppModule.class, NetModule.class}) public interface NetComponent { Retrofit retrofit(); } |
et dans le MyApplication qui étend la classe Application
d'Android :
1 2 3 4 5 | // Dagger mNetComponent = DaggerNetComponent.builder() .appModule(new AppModule(this)) .netModule(new NetModule(Configuration.url)) .build(); |
La partie MVP
Le module permettant d'injecter la vue :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @Module public class MyModule { private final MyContract.View mView; public MyModule(MyContract.View view) { mView = view; } @Provides MyContract.View provideView() { return mView; } } |
Le component :
1 2 3 4 5 | @FragmentScoped @Component(dependencies = NetComponent.class, modules = MyModule.class) public interface MyComponent { void inject(MyFragment fragment); } |
Mon presenter :
1 2 3 4 5 | @Inject MyPresenter(Retrofit retrofit, MyContrat.View myView) { this.retrofit = retrofit; this.myView = myView; } |
Et le fragment :
1 2 3 4 | DaggerMyComponent.builder() .netComponent(((MyApp) getActivity().getApplication()).getNetComponent()) .MyModule(new MyModule(this)) .build().inject(this); |
Tout marche bien dans le meilleur des monde, mais la deuxième ligne de mon fragment (qui semble indispensable) me surprend, pourquoi suis-je obligé de re-préciser mon netComponent alors que l'ai déjà fait dans ma classe MyApplication ? Y'a t-il pas un autre moyen de faire pour éviter cette répétition.
Merci d'avance.