Ralph
Ralph

Reputation: 578

Dagger 2 and Android Databinding Adapter: cannot be provided without an @Inject or @Provides

I'm using Android's Databinding library and Dagger 2. I wanted to make use of a DatabingAdapter in displaying my images in the RecyclerView. I have my Picasso instance created using Dagger and I have to inject it inside the DatabindingAdapter that I created. I followed this tutorial here and I'm getting the error that Picasso cannot be provided without @Inject or @Provides annotated method. Here's my code (classes are simplified to focus more on this issue, I got Picasso already working before).

AppModule.java

@Module(includes = {AndroidInjectionModule.class, NetworkModule.class, ViewModelModule.class})
public class AppModule {

    @Provides
    @AppScope
    Picasso picasso(App app, OkHttp3Downloader okHttp3Downloader) {
        return new Picasso.Builder(app.getApplicationContext())
                .downloader(okHttp3Downloader)
                .indicatorsEnabled(true)
                .build();
    }
}

BindingModule.java

@Module
public class BindingModule {
    @BindingScope
    @Provides
    ImageBindingAdapter provideImageBindingAdapter(Picasso picasso) {
        return new ImageBindingAdapter(picasso);
    }
}

BindingComponent.java

@BindingScope
@Component(dependencies = AppComponent.class, modules = BindingModule.class)
public interface BindingComponent extends androidx.databinding.DataBindingComponent {
}

AppComponent.java

@AppScope
@Component(modules = {AppModule.class, AndroidSupportInjectionModule.class, ActivityBuildersModule.class})
public interface AppComponent {

    void inject(App app);

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(App application);

        AppComponent build();
    }
}

ImageBindingAdapter.java

public class ImageBindingAdapter {

    private final Picasso picasso;

    public ImageBindingAdapter(Picasso picasso) {
        this.picasso = picasso;
    }

    @BindingAdapter(value = "url")
    public void loadImageUrl(ImageView imageView, String url) {
        if (url != null && !url.trim().isEmpty())
            picasso.load(Constants.ENDPOINT + url).into(imageView);
    }
}

And here's what the error is.

error: [Dagger/MissingBinding] com.squareup.picasso.Picasso cannot be provided without an @Inject constructor or an @Provides-annotated method.
com.squareup.picasso.Picasso is injected at
com.ralphevmanzano.themoviedb.di.modules.BindingModule.provideImageBindingAdapter(picasso)
com.ralphevmanzano.themoviedb.databinding.ImageBindingAdapter is provided at
androidx.databinding.DataBindingComponent.getImageBindingAdapter()

Any help is much appreciated.

Upvotes: 2

Views: 1046

Answers (1)

Samuel Eminet
Samuel Eminet

Reputation: 4737

You're missing @Inject annotation from your ImageBindingAdapter class

@AppScope
public class ImageBindingAdapter {

    private final Picasso picasso;

    @Inject
    public ImageBindingAdapter(Picasso picasso) {
        this.picasso = picasso;
    }

    @BindingAdapter(value = "url")
    public void loadImageUrl(ImageView imageView, String url) {
        if (url != null && !url.trim().isEmpty())
            picasso.load(Constants.ENDPOINT + url).into(imageView);
    }
}

Adding @Inject tell dagger to add this class to graph, then you can add your scope annotation to your class to tell in which scope this class is added.

ps : You can remove your BindingModuleclass

Upvotes: 4

Related Questions