2017-08-07 5 views
0

SCOPED Hé, j'ai trois composants:Dagger2 composants dépend de plus d'un composant

  • Application -> fournir un contexte (par exemple LocationUsecase)

  • ApiService -> fournir Retrofit (repos appels)

  • DBService -> fournir RoomDB (sauf dans SQLite)

Parfois, je veux utiliser plus d'un composant dans mon ViewModel - mais je cours dans l'exception où je ne peux pas .inject(ViewModel) la même classe à de nombreux composants.

UserViewModel{ 
    @Inject ApiService api; 
    @Inject DatabaseService db; 

    public User(){ 
    Application.getApiComponent.inject(this) 
    Application.getDBComponent.inject(this) 
    } 

} 

Parce que je veux avoir des composants decopuled (pour des fins de test) j'ai décidé d'ajouter des dépendances à mon ApplicationComponent, et quand Injecter en application pour pouvoir utiliser albo DB, et REST

@PerApplication 
@Component(dependencies = {DBComponent.class, RestApiComponent.class}, 
     modules = {ApplicationModule.class}) 
public interface ApplicationComponent{...} 

@DbScope 
@Component(modules = {DBModule.class}) 
public interface DBComponent {...} 

@RestScope 
@Component(modules = {RestApiRetrofitModule.class}) 
public interface RestApiComponent {...} 

Cette fois, je lance dans la compilation eRREUR:

PerApplication ApplicationComponent dépend de plus d'un composant scope: @DbScope DBComponent @RestScope RestApiComponent

Le problème est que je n'ai trouvé AUCUN exemple quand les gens utilisent plus d'une depencecies - est-ce restreint? Lorsque je supprime @Scope de DBComponent c'est bien - mais j'ai instance non délimitée qui retournera à chaque fois nouvelle instance Lorsque je supprime un composant de dépendances, je vais également construire sans erreur. Comment puis-je utiliser deux dépendances dans mon composant?

Répondre

2

Vous y êtes presque - les dependencies = doit aller dans la personne à charge (enfant) composants

@PerApplication 
@Component(modules = ApplicationModule.class) 
public interface ApplicationComponent{...} 

@DbScope 
@Component(dependencies = ApplicationComponent.class, modules = DBModule.class) 
public interface DBComponent {...} 

@RestScope 
@Component(dependencies = ApplicationComponent.class, modules = RestApiRetrofitModule.class) 
public interface RestApiComponent {...} 

Maintenant, assurez-vous de exposez les dépendances qui sont liés dans l'ensemble du module pour ApplicationComponent afin que la les composants dépendants peuvent les utiliser.

Donc, si vous liez un SharedPreferences à ApplicationComponent niveau et que vous voulez que la dépendance à partager avec les composants dépendants dont vous aurez besoin d'écrire une méthode de disposition dans le ApplicationComponent

@Component 
public interface ApplicationComponent { 

    SharedPreferences exposeSharedPreferences(); 
} 

En outre, vous voudrez peut-être reconsidérer faire des étendues juste pour DB et REST - ce sont plutôt des groupements de fonctionnalités et le découplage que vous désirez peut être accompli avec des modules.

Normalement, vous n'avez besoin que de quelques portées dans une application Android: une portée @PerApp et une portée @PerActivity étant donné que les portées suivent les cycles de vie et que ce sont les deux principaux cycles de vie.

+0

Merci pour la réponse. Dans votre exemple, DBScope devient la portée parente de PerApplication? Et lors de l'initialisation de Dagger_DBComponent.builder j'obtiendra la portée de l'enfant (ApplicationComponent)? C'est sympa, je vais essayer le plus vite possible, mais des questions demeurent: "Est-il possible d'utiliser plus d'une dépendance?" – murt

+0

@murt pour répondre directement à votre question, il n'est pas possible d'avoir un composant qui dépend de plus d'un composant. Voir [cette réponse] (https://stackoverflow.com/a/44178673/5241933) pour une explication pourquoi –

+0

Aussi, dans l'exemple '@ PerApplication' est la portée racine. '@ DbScope' et' @ RestScope' seraient des étendues plus étroites –