0
votes

I tried to use dagger 2 for the first time in one of my apps. Im getting error at dagger component class as the class did not get generated. please help me to get it work.

Link to my app https://github.com/kantigaricharan/Zolo

This the Error

    02:45:55.663 [ERROR] [system.err] /Users/vamsikrishna/Downloads/Zolo/app/src/main/java/com/example/saicharan/zolo/dagger/component/AppComponent.java:17: error: com.example.saicharan.zolo.dashboard.DashboardInteractorImpl cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.
02:45:55.663 [ERROR] [system.err]     void inject(MyApp myApp);
02:45:55.663 [ERROR] [system.err]          ^
02:45:55.663 [ERROR] [system.err]       com.example.saicharan.zolo.dashboard.DashboardInteractorImpl is injected at
02:45:55.663 [ERROR] [system.err]           com.example.saicharan.zolo.MyApp.dashboardInteractor
02:45:55.664 [ERROR] [system.err]       com.example.saicharan.zolo.MyApp is injected at
02:45:55.664 [ERROR] [system.err]           com.example.saicharan.zolo.dagger.component.AppComponent.inject(myApp)
02:45:55.722 [ERROR] [system.err] 1 error

This is my Component class in dagger

   @Singleton @Component(modules = AppModule.class)
public interface AppComponent {
    void inject(MyApp myApp);
    void inject(DashboardInteractorImpl dashboardInteractorImpl);
}

This is module

    @Module
public class AppModule {
    private final MyApp myApp;
    public AppModule(MyApp myApp){this.myApp=myApp;}

    @Provides @Singleton
    Context providesApplicationContext(){
        return myApp;
    }
    @Provides @Singleton
    SessionManagement getSession(Context context){
        return  new SessionManagement(myApp);
    }
    @Provides @Singleton
    DatabaseHelper getDhelper(Context context){
        return new DatabaseHelper(myApp);
    }
}

Application class

    public class MyApp extends Application {

    protected AppComponent appComponent;
    private static MyApp instance;
    @Inject
    DashboardInteractorImpl dashboardInteractor;

    public static MyApp getInstance() {
        return instance;
    }

    public static Context getContext(){
       // return (MyApp) context.getApplicationContext();
          return instance.getApplicationContext();
    }

    @Override
    public void onCreate() {
        instance = this;
        super.onCreate();
        appComponent = DaggerAppComponent
                .builder()
                .appModule(new AppModule(this))
                .build();
        appComponent.inject(this);
    }
    public AppComponent getAppComponent(){
        return appComponent;
    }
}

DasboardInteractorImpl

   public class DashboardInteractorImpl implements DashboardInteractor {

    private final DatabaseHelper dHelper;
    private final SessionManagement sManager;
    DashboardPresenterImpl mDashboardPresenter;

    public DashboardInteractorImpl(DashboardPresenterImpl mDashboardPresenter){
        this.mDashboardPresenter=mDashboardPresenter;

        dHelper = new DatabaseHelper(MyApp.getContext());
        sManager= new SessionManagement(MyApp.getContext());
    }
     //SOME LOGIC HERE..
}

Can i know what went wrong with my app?

4
Did you rebuild your project after creating modules and components? - eurosecom
get rid of apply plugin: 'com.neenbedankt.android-apt' - all of your apt should be replaced by annotationProcessor if possible - David Rawson
@eurosecom Yeah i have done that but still didn't resolve the error - charan reddy
@DavidRawson Its now giving Gradle dsl method not found apt, when i tried to sync the gradle - charan reddy
You still have apt for ButterKnife apt 'com.jakewharton:butterknife-compiler:8.8.0' - check the ButterKnife page for the correct lines to put in the gradle - David Rawson

4 Answers

2
votes

When you want Dagger 2 to provide a class for you, make sure you annotate the constructor with an @Inject annotation:

@Inject
public DashboardInteractorImpl(DashboardPresenterImpl mDashboardPresenter){
    this.mDashboardPresenter=mDashboardPresenter;

    dHelper = new DatabaseHelper(MyApp.getContext());
    sManager= new SessionManagement(MyApp.getContext());
}

Also, get rid of the line for injecting in your app:

@Singleton @Component(modules = AppModule.class)
public interface AppComponent {
   void inject(MyApp myApp);

   //delete the line below:
   //void inject(DashboardInteractorImpl dashboardInteractorImpl);
}

You will also need to make sure that Dagger 2 can provide DashboardPresenterImpl either by annotating the constructor for the presenter with @Inject or by writing a @Provides method inside a module.

0
votes

Try using following modification

// Component
@Singleton @Component(modules = AppModule.class)
public interface AppComponent {
    void inject(MyApp myApp);

    DashboardInteractorImpl getDashboardInteractorImpl();
}

// Module
@Module 
public class AppModule { 
    private final MyApp myApp;
    public AppModule(MyApp myApp){this.myApp=myApp;}

    @Provides @Singleton 
    Context providesApplicationContext(){
        return myApp;
    } 
    @Provides @Singleton 
    SessionManagement getSession(Context context){
        return  new SessionManagement(context);
    } 
    @Provides @Singleton 
    DatabaseHelper getDhelper(Context context){
        return new DatabaseHelper(context);
    } 
}

// Application
public class MyApp extends Application {

    protected AppComponent appComponent;
    private static MyApp instance;
    @Inject 
    DashboardInteractorImpl dashboardInteractor;

    public static MyApp getInstance() { 
        return instance;
    } 

    public static Context getContext(){
       // return (MyApp) context.getApplicationContext(); 
          return instance.getApplicationContext();
    } 

    @Override 
    public void onCreate() { 
        instance = this;
        super.onCreate(); 
        appComponent = DaggerAppComponent
                .builder() 
                .appModule(new AppModule(this))
                .build(); 
        appComponent.inject(this);
    } 
    public AppComponent getAppComponent(){ 
        return appComponent;
    } 
} 

// DashboardInteractorImpl
public class DashboardInteractorImpl implements DashboardInteractor {

    private final DatabaseHelper dHelper;
    private final SessionManagement sManager;
    private DashboardPresenterImpl mDashboardPresenter;

    @Inject 
    public DashboardInteractorImpl(DatabaseHelper databaseHelper,
                SessionManagement sessionManagement
                DashboardPresenterImpl dashboardPresenter){

        dHelper = databaseHelper;
        sManager = sessionManagement;
        mDashboardPresenter = dashboardPresenter;
    }
     //SOME LOGIC HERE..
}

// DashboardPresenterImpl
public class DashboardPresenterImpl implements DashboardPresenter {

    @Inject     
    public DashboardPresenterImpl(ABC abc){
        //make sure ABC is provided by the module or inject on constructed
    }
}
0
votes

You can inject DashboardInteractorImpl with two ways.

Either you have to Declare DashboardInteractorImpl Dependency in App module.

Or

You can write @Inject constructor. I did not see any code that full fill this Dependency. so you can do two thing you can Provide this DashboardPresenterImpl, DashboardInteractorImpl in module or Create @Inject constructor for each of this class DashboardPresenterImpl, DashboardInteractorImpl.

-1
votes

If you use or write code in Kotlin add this line code inside build.gradle

apply plugin: 'kotlin-kapt'