问题
I'm using the new Dagger2 (ver 2.11) and I'm using the new features like AndroidInjector
, and ContributesAndroidInjector
. I have an activity subcomponent,
@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();
}
And the UserListModule
provides dependencies for the fragment. Some of the dependencies I just want to bind the instances , and return , like
@Binds
@ActivityScope
abstract UserListView mUserListView(UserListFragment userListFragment);
Instead of simply just return the dependency , like
@Provides
@ActivityScope
UserListView mUserListView(UserListFragment userListFragment){
return userListFragment;
}
My module contains some @Provides
methods as well. Can we use both @Binds
and @Provides
methods in the same module? I tried as shown below
@Module
public abstract class UserListModule {
@Provides
@ActivityScope
UserListFragment mUserListFragment() {
return new UserListFragment();
}
@Binds
@ActivityScope
abstract UserListView mUserListView(UserListFragment userListFragment);
// other provides and binds methods...
......
.....
}
And it its throwing error
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.
Is there any way to do this?
回答1:
@Binds
and @ContributesAndroidInjector
methods must be abstract, because they don't have method bodies. That means that they must go on an interface or abstract class. @Provides
methods may be static
, which means they can go on abstract classes and Java-8-compiled interfaces, but non-static ("instance") @Provides
methods don't work on abstract classes. This is explicitly listed in the Dagger FAQ, under the sections "Why can’t @Binds and instance @Provides methods go in the same module?" and "What do I do instead?".
If your @Provides
method doesn't use instance state, you can mark it static
, and it can go onto an abstract class adjacent to your @Binds
methods. If not, consider putting the bindings like @Binds
and @ContributesAndroidInjector
into a separate class--possibly a static nested class--and including that using the includes
attribute on Dagger's @Module
annotation.
回答2:
A little addition to Jeff's solution above:
you may create inner interface instead of static inner class, like this:
@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);
}
}
来源:https://stackoverflow.com/questions/46618763/dagger2-how-to-use-provides-and-binds-in-same-module