Ibrahim Disouki
Ibrahim Disouki

Reputation: 2693

Dagger 2 For Android "cannot be provided without an @Provides-annotated method"

I'm trying to use the latest version of Dagger 2 V2.11 for Android Here is my code:
AppComponent:

@Singleton
@Component(modules = {
        AndroidInjectionModule.class,
        AppModule.class,
        ActivityBuildersModule.class,
        FragmentBuildersModule.class
})
public interface AppComponent {
    void inject(MyApplication myApplication);

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

        AppComponent build();
    }

    @ExceptionRequestsQualifier
    ExceptionRequestsServices exceptionRequestsServices();

}

AppModule:

@Module(includes = {ActivityModule.class, FragmentModule.class})
public class AppModule {

    @Provides
    CompositeDisposable provideCompositeDisposable() {
        return new CompositeDisposable();
    }

    @Provides
    @ExceptionRequestsQualifier
    ExceptionRequestsServices provideExceptionRequests() {
        return new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(APIConstants.EXCEPTION_REQUESTS_BASE_URL)
                .build()
                .create(ExceptionRequestsServices.class);
    }

    @Singleton
    @Provides
    NetworkManager provideNetworkManager(Application app) {
        return new NetworkManager(app);
    }

}

ActivityBuildersModule:

@Module
public abstract class ActivityBuildersModule {

    @ActivityScope
    @ContributesAndroidInjector
    abstract ExceptionRequestsActivity contributeExceptionRequestsActivity();

}

ActivityModule:

@Module()
public abstract class ActivityModule {

    @Provides
    @ActivityScope
    static ExceptionRequestsMvpPresenter<ExceptionRequestsMvpView> bindExceptionRequestsPresenter(
            ExceptionRequestsPresenter<ExceptionRequestsMvpView> presenter) {
        return presenter;
    }

}

FragmentBuildersModule:

@Module
public abstract class FragmentBuildersModule {

    @FragmentScope
    @ContributesAndroidInjector
    abstract AddApplicantFragment contributeAddApplicantFragment();

    @FragmentScope
    @ContributesAndroidInjector
    abstract PledgeFragment contributePledgeFragment();

}

FragmentModule:

@Module()
public abstract class FragmentModule {

    @Provides
    @FragmentScope
    static AddApplicantMvpPresenter<AddApplicantMvpView> bindAddApplicantPresenter(
            AddApplicantPresenter<AddApplicantMvpView> presenter) {
        return presenter;
    }

    @Provides
    @FragmentScope
    static PledgeMvpPresenter<PledgeMvpView> bindPledgePresenter(
            PledgePresenter<PledgeMvpView> presenter) {
        return presenter;
    }

}

AddApplicantPresenter:

public class AddApplicantPresenter<V extends AddApplicantMvpView> extends BasePresenter<V> implements AddApplicantMvpPresenter<V> {

    @Inject
    @ExceptionRequestsQualifier
    ExceptionRequestsServices mExceptionRequestsServices;

    @Inject
    NetworkManager mNetworkManager;

    @Inject
    public AddApplicantPresenter(CompositeDisposable compositeDisposable) {
        super(compositeDisposable);
    }

}

AddApplicantMvpPresenter:

@FragmentScope
public interface AddApplicantMvpPresenter<V extends AddApplicantMvpView> extends MvpPresenter<V> {

    void addApplicant(String name, String qatarId,
                      String date, String mobile,
                      ChosenImage chosenImage);

}

ActivityScope:

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}

FragmentScope:

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface FragmentScope {
}

Error Log:

Error:(21, 1) error: mypackagename.di.component.AppComponent scoped with @Singleton may not reference bindings with different scopes:
@Provides @mypackagename.di.scope.ActivityScope mypackagename.ui.exceptionrequests.ExceptionRequestsMvpPresenter<mypackagename.ui.exceptionrequests.ExceptionRequestsMvpView> mypackagename.di.module.ActivityModule.bindExceptionRequestsPresenter(mypackagename.ui.exceptionrequests.ExceptionRequestsPresenter<mypackagename.ui.exceptionrequests.ExceptionRequestsMvpView>)
@Provides @mypackagename.di.scope.FragmentScope mypackagename.ui.addapplicant.AddApplicantMvpPresenter<mypackagename.ui.addapplicant.AddApplicantMvpView> mypackagename.di.module.FragmentModule.bindAddApplicantPresenter(mypackagename.ui.addapplicant.AddApplicantPresenter<mypackagename.ui.addapplicant.AddApplicantMvpView>)
@Provides @mypackagename.di.scope.FragmentScope mypackagename.ui.pledge.PledgeMvpPresenter<mypackagename.ui.pledge.PledgeMvpView> mypackagename.di.module.FragmentModule.bindPledgePresenter(mypackagename.ui.pledge.PledgePresenter<mypackagename.ui.pledge.PledgeMvpView>)

Upvotes: 4

Views: 5417

Answers (1)

Jileshl
Jileshl

Reputation: 161

Modules & Components can't have different Scopes You can have Components to have multiple Scopes and this can solve it. Try to move it to different component and add it as component dependencies

I hope in future they can solve this, the way I've done it in my project. Currently, Dagger2 allows module with NoScope & single scope. This should match with your components.

Thumb Rule:: Different scopes have different components. For your application, you need three components, FragmentComponent (FragmentScope) :- (Ideally this should be ActivityComponent) ApplicationComponent (Singleton)

https://medium.com/@patrykpoborca/making-a-best-practice-app-4-dagger-2-267ec5f6c89a Read more about scopes.

Upvotes: 4

Related Questions