J'utilise le nouveau Dagger2 (ver 2.11) et j'utilise les nouvelles fonctionnalités comme AndroidInjector
et ContributesAndroidInjector
. J'ai un sous-composant d'activité,
@Module
abstract class ActivityBuilderModule {
@ContributesAndroidInjector(modules =
{UserListModule.class, MainFragmentModule.class})
@ActivityScope
abstract MainActivity bindsMainActivity();
}
@Module
public abstract class MainFragmentModule {
@ContributesAndroidInjector
@FragmentScope
@FragmentKey(UserListFragment.class)
abstract UserListFragment bindsUserListFragment();
}
Et le UserListModule
fournit des dépendances pour le fragment. Certaines des dépendances que je veux simplement lier les instances et retourner, comme
@Binds
@ActivityScope
abstract UserListView mUserListView(UserListFragment userListFragment);
Au lieu de simplement renvoyer la dépendance, comme
@Provides
@ActivityScope
UserListView mUserListView(UserListFragment userListFragment){
return userListFragment;
}
Mon module contient également quelques méthodes @Provides
. Pouvons-nous utiliser les méthodes @Binds
Et @Provides
Dans le même module? J'ai essayé comme indiqué ci-dessous
@Module
public abstract class UserListModule {
@Provides
@ActivityScope
UserListFragment mUserListFragment() {
return new UserListFragment();
}
@Binds
@ActivityScope
abstract UserListView mUserListView(UserListFragment userListFragment);
// other provides and binds methods...
......
.....
}
Et c'est son erreur de lancement
Error:(22, 8) error: dagger.internal.codegen.ComponentProcessor was unable to process this interface because not all of its dependencies could be resolved. Check for compilation errors or a circular dependency with generated code.
Y a-t-il un moyen de faire ça?
@Binds
et @ContributesAndroidInjector
les méthodes doivent être abstraites, car elles n'ont pas de corps de méthode. Cela signifie qu'ils doivent aller sur une interface ou une classe abstraite. @Provides
les méthodes peuvent être static
, ce qui signifie qu'elles peuvent aller sur des classes abstraites et des interfaces compilées en Java-8, mais non statiques ("instance") @Provides
les méthodes ne fonctionnent pas sur les classes abstraites. Ceci est explicitement répertorié dans la FAQ Dagger, sous les sections "Pourquoi ne peut pas @Binds
et instance @Provides
les méthodes vont dans le même module? " et " Que dois-je faire à la place? " .
Si ton @Provides
la méthode n'utilise pas l'état d'instance, vous pouvez le marquer static
, et il peut aller sur une classe abstraite adjacente à votre @Binds
méthodes. Sinon, pensez à mettre les liaisons comme @Binds
et @ContributesAndroidInjector
dans une classe distincte - peut-être une classe imbriquée statique - et en incluant celle-ci en utilisant l'attribut includes
sur le @Module
annotation.
Un petit ajout à la solution de Jeff ci-dessus:
vous pouvez créer une interface interne au lieu d'une classe interne statique, comme ceci:
@Module(includes = AppModule.BindsModule.class)
public class AppModule {
// usual non-static @Provides
@Provides
@Singleton
Checkout provideCheckout(Billing billing, Products products) {
return Checkout.forApplication(billing, products);
}
// interface with @Binds
@Module
public interface BindsModule {
@Binds
ISettings bindSettings(Settings settings);
}
}