Dagger 2 et le pattern mvp sous Android

Le problème exposé dans ce sujet a été résolu.

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.

+0 -0

Salut Hugo,

Malheureusement, je ne connais que Dagger de Square. Cela dit, à la lecture de ton message et de ton problème, je ne comprends pas ce qui te chipote. Quand tu dis que tu ne comprends pas pourquoi tu de re-préciser ton netComponent, où est-ce que tu le précises autre part ? Tu parles de sa déclaration ?

1
2
3
4
mNetComponent = DaggerNetComponent.builder()
  .appModule(new AppModule(this))
  .netModule(new NetModule(Configuration.url))
  .build();

Désolé, j'ai pas pris le temps de répondre mais c'était un peu compliqué de prendre ce temps là.

Je parlais effectivement de sa déclaration, j'ai l’impression de lui dire deux fois que mon netModule, correspond à cet instance de NetModule. J'aurais aimé que sa soit optionnel et que si tu le déclare un jour, Dagger 2 soit capable de se dire « tiens il veut une instance de Retrofit et j'ai déjà ça dans mon catalogue » surtout quand c'est un @Singleton.

Je crois que je cherchais fonctionnellement un truc comme guice mais bon apparemment Google ne recommande pas.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte