12

I am migrating to the new dagger android 2.11

All set up based on the Google blueprint :MVP-Dagger.but I am having this error :

Error:(22, 57) error: @Binds methods must have only one parameter whose type is assignable to the return type

Here in this line :

   @ActivityScoped
    @Binds abstract PresenterFactory<MainContract.Presenter> providePresenterFactory(MainPresenter presenter);

The presenter :

@ActivityScoped
public class MainPresenter extends BasePresenterImpl<MainContract.View>
    implements MainContract.Presenter { public MainPresenter(String s) {..
} ... }

Someone have any idea on how to solve this? Thanks.

Mohamed ALOUANE
  • 5,349
  • 6
  • 29
  • 60

3 Answers3

22

The error message explains everything:

@Binds methods must have only one parameter whose type is assignable to the return type

Your @Binds method has a parameter of MainPresenter. This is not assignable to the return type PresenterFactory<MainContract.Presenter>. In other words, MainPresenter is not an instance of PresenterFactory<MainContract.Presenter>.

The correct syntax for @Binds methods is something like:

@Binds
abstract Abstraction bindAbstration(Concretion concretion)

where concretion is an instance of Abstraction.

Or, in Kotlin:

@Binds
abstract fun bindAbstraction(concretion: Concretion) : Abstraction

@Binds methods are not magic. They bind a type (for instance, an interface) and an implementation of that type that Dagger knows how to provide already.

update

You can convert your @Provides to @Binds with the following steps:

  1. Make sure MainPresenter has an explicit constructor annotated with @Inject and that Dagger 2 can provide the dependencies in the constructor.
  2. Write:

    @Binds
    abstract MainContract.Presenter bindPresenter(MainPresenter mainPresenter);
    
David Rawson
  • 20,912
  • 7
  • 88
  • 124
  • I see , the Provide one is work just fine. how can i convert it to Binds one ? @ ActivityScoped @ Provides public PresenterFactory providePresenterFactory( DataManager mDataManager) { return MainPresenter::new; } FYI : PresenterFactory is an interface while the presenter it selft extends from BasePresenterImpl – Mohamed ALOUANE Oct 10 '17 at 20:45
  • Not working because the type of presenter instance is injected like this : @Inject PresenterFactory mPresenterFactory; – Mohamed ALOUANE Oct 11 '17 at 20:51
  • `abstract Abstraction bindAbstration(Concretion concretion)` this is the ultimate mantra to explain it. – Eido95 Oct 28 '18 at 15:12
3

I had the same exception but in a different situation.

The exception was misleading for me. After adding

kapt {
 correctErrorTypes true 
} 

to build.gradle I found the real problem:

error: [ComponentProcessor:MiscError] dagger.internal.codegen.ComponentProcessor was 
unable to process this class because not all of its dependencies could be resolved.
Check for compilation errors or a circular dependency with generated code.

and the hint not all of its dependencies could be resolved helped me to find out that I missed adding implementation project(path: ':repository') to build.gradle of my app module which handles DI stuff.

Hope this help others having same problem.

Fartab
  • 4,725
  • 2
  • 26
  • 39
-6

Use @Provides instead of @Binds

k4dima
  • 6,070
  • 5
  • 41
  • 39