Search code examples
javaandroidandroid-studiodependency-injectiondagger

Android Dagger error cannot find symbol class DaggerDashboardComponent


I am working on an existing project that uses Dagger.

This is my first attempt at using dagger, and I am little bit lost with this.

I have tried replicating all of the existing classes, interfaces and everything else from an existing fragment / module / component, and I am getting the following error:

Error:(7, 42) error: cannot find symbol class DaggerDashboardComponent

I tried Clean Project and Rebuild Project, I tried Invalidate Caches and Restart, I enabled the annotation feature from the compiler settings of Android Studio, I tried closing the project and reopening it, but for some reason (probably some mistake in the classes generation), I am not able to compile as dagger is not generating the needed classes.

Please find below all of the classes / interfaces I created:

FragmentDashboard:

package com.example.app.ui.dashboard;

import com.example.app.R;
import com.example.app.base.AbstractRequestFragment;
import com.example.app.databinding.FragmentDashboardBinding;
import com.example.app.di.component.AppComponent;
import com.example.app.di.component.DaggerDashboardComponent;
import com.example.app.di.module.DashboardModule;
import com.example.app.presenter.dashboard.DashboardPresenter;
import com.example.app.ui.dashboard.DashboardView;

import javax.inject.Inject;

import retrofit2.Call;

/**
 * Created by on 31-05-2017.
 */
public class FragmentDashboard extends AbstractRequestFragment<FragmentDashboardBinding> implements DashboardView {

    @Inject
    DashboardPresenter dashboardPresenter;

    @Override
    protected int layoutToInflate() {
        return R.layout.fragment_dashboard;
    }

    @Override
    protected void injectComponent(AppComponent appComponent) {
        DaggerDashboardComponent.builder()
                .appComponent(appComponent)
                .dashboardModule(new DashboardModule(this))
                .build()
                .inject(this);
    }

    @Override
    protected void initializePresenter(FragmentDashboardBinding fragmentDashboardBinding) {
        dashboardPresenter.initialize(fragmentDashboardBinding);
    }

    @Override
    public void addRequestToStack(Call<?> call) {
        addRequest(call);
    }
}

DashboardComponent:

package com.example.app.di.component;

import com.example.app.di.module.DashboardModule;
import com.example.app.di.scope.Fragment;
import com.example.app.presenter.dashboard.DashboardPresenter;
import com.example.app.ui.dashboard.DashboardView;
import com.example.app.ui.dashboard.FragmentDashboard;

import dagger.Component;

/**
 * Created by on 31-05-2017.
 */
@Fragment
@Component(modules = DashboardModule.class, dependencies = AppComponent.class)
public interface DashboardComponent {

    /* BASE */
    void inject(FragmentDashboard fragmentDashboard);

    /* DASHBOARD */
    DashboardView providesDashboardView();
    DashboardPresenter providesDashboardPresenter();

}

Dashboard Module:

package com.example.app.di.module;

import com.example.app.di.scope.Fragment;
import com.example.app.ui.dashboard.DashboardView;

import dagger.Module;
import dagger.Provides;

/**
 * Created by on 31-05-2017.
 */
@Module
public class DashboardModule {

    private DashboardView view;

    public DashboardModule(DashboardView view) {
        this.view = view;
    }

    @Fragment
    @Provides
    public DashboardView providesDashboardView() {
        return view;
    }


}

DashboardPresenter:

package com.example.app.presenter.dashboard;

import com.example.app.base.BasePresenter;
import com.example.app.databinding.FragmentDashboardBinding;
import com.example.app.databinding.FragmentLoginBinding;

/**
 * Created by on 31-05-2017.
 */
public interface DashboardPresenter extends BasePresenter<FragmentDashboardBinding> {
}

DashboardPresenterImpl:

package com.example.app.presenter.dashboard;

import android.content.Intent;
import android.view.MotionEvent;
import android.view.View;

import com.massivedisaster.activitymanager.ActivityFragmentManager;
import com.example.app.api.ApiListener;
import com.example.app.base.ActivityFullScreen;
import com.example.app.databinding.FragmentDashboardBinding;
import com.example.app.databinding.FragmentLoginBinding;
import com.example.app.presenter.dashboard.DashboardPresenter;
import com.example.app.ui.login.LoginView;
import com.example.app.ui.main.FragmentMain;
import com.example.app.util.ApiManager;
import com.example.app.util.OnOneClickListener;
import com.example.app.util.OnTouchListener;
import com.example.app.util.SnackbarHandler;
import com.example.app.util.ViewHelper;
import com.example.app.util.factory.LoginFactory;

import java.util.ArrayList;

/**
 * Created by on 31-05-2017.
 */
public class DashboardPresenterImpl implements DashboardPresenter {

    private ApiManager apiManager;
    private FragmentDashboardBinding fragmentBinding;
    private LoginFactory loginFactory;
    private LoginView loginView;
    private ViewHelper viewHelper;

    public DashboardPresenterImpl(ApiManager apiManager, LoginFactory loginFactory, LoginView loginView, ViewHelper viewHelper) {
        this.apiManager = apiManager;
        this.loginFactory = loginFactory;
        this.loginView = loginView;
        this.viewHelper = viewHelper;
    }

    @Override
    public void initialize(FragmentDashboardBinding fragmentBinding) {
        this.fragmentBinding = fragmentBinding;

        this.fragmentBinding.btnLogin.setOnClickListener(new OnLoginClickListener());

        // apply on touch cleanup to view and all elements within view
        ArrayList<View> touchables = fragmentBinding.getRoot().getTouchables();
        touchables.add(fragmentBinding.getRoot());
        for (View v : touchables) {
            v.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    return super.onTouch(view, motionEvent);
                }
            });
        }
    }


    // main login listener
    private class OnLoginClickListener extends OnOneClickListener {

        @Override
        public void doOnClick(View view) {
            Intent intent = ActivityFragmentManager.getIntent(loginView.getActivity(), ActivityFullScreen.class, FragmentMain.class);

            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

            loginView.getActivity().startActivity(intent);
        }
    }


}

DashboardView:

package com.example.app.ui.dashboard;

import com.example.app.base.RequestView;

/**
 * Created by on 31-05-2017.
 */
public interface DashboardView extends RequestView {

}

Fragment Dashboard:

package com.example.app.ui.dashboard;

import com.example.app.R;
import com.example.app.base.AbstractRequestFragment;
import com.example.app.databinding.FragmentDashboardBinding;
import com.example.app.di.component.AppComponent;
import com.example.app.di.component.DaggerDashboardComponent;
import com.example.app.di.module.DashboardModule;
import com.example.app.presenter.dashboard.DashboardPresenter;
import com.example.app.ui.dashboard.DashboardView;

import javax.inject.Inject;

import retrofit2.Call;

/**
 * Created by on 31-05-2017.
 */
public class FragmentDashboard extends AbstractRequestFragment<FragmentDashboardBinding> implements DashboardView {

    @Inject
    DashboardPresenter dashboardPresenter;

    @Override
    protected int layoutToInflate() {
        return R.layout.fragment_dashboard;
    }

    @Override
    protected void injectComponent(AppComponent appComponent) {
        DaggerDashboardComponent.builder()
                .appComponent(appComponent)
                .dashboardModule(new DashboardModule(this))
                .build()
                .inject(this);
    }

    @Override
    protected void initializePresenter(FragmentDashboardBinding fragmentDashboardBinding) {
        dashboardPresenter.initialize(fragmentDashboardBinding);
    }

    @Override
    public void addRequestToStack(Call<?> call) {
        addRequest(call);
    }
}

Can anyone tell what I am missing here?


Solution

  • You try to inject the interface DashboardPresenter. But dagger cannot satisfy interface dependencies because it doesn't know which implementation you want. There are two ways to get around this problem:

    Solution 1 with @Provide

    @Provides
    public DashboardPresenter providesDashboardPresenter() 
    {
        return new DashboardPresenterImpl(...);
    }
    

    Solution 2 with @Binds

    @Binds
    abstract DashboardPresenter provideDashboardPresenter(DashboardPresenterImpl impl);
    

    Add @Inject to constructor of DashboardPresenterImpl. Make sure that dagger can construct the dependencies of the constructor or provide instances via @Provide in a module.

    public class DashboardPresenterImpl implements DashboardPresenter {
    
        private ApiManager apiManager;
        private FragmentDashboardBinding fragmentBinding;
        private LoginFactory loginFactory;
        private LoginView loginView;
        private ViewHelper viewHelper;
    
        @Inject
        public DashboardPresenterImpl(ApiManager apiManager, LoginFactory loginFactory, LoginView loginView, ViewHelper viewHelper) {
            this.apiManager = apiManager;
            this.loginFactory = loginFactory;
            this.loginView = loginView;
            this.viewHelper = viewHelper;
        }
    }
    

    There are maybe more errors like Ignacio Tomas Crespo already said. So please provide more information and show us the compiler errors.