VIPER Inject Interactor in Presenter

I have an app with VIPER architecture. I use DI with dagger-2 but I can’t inject the interactor into presenter.

I obtain the next error:

lateinit property interactor has not been initialized

I have the next Code:

MainView (Kotlin)

interface MainView {

    interface View : BaseView {
        showMessage(message : String)
    }

    interface InteractorOutput{
        ...
    }
}

MainActivity (Kotlin)

class MainActivity : BaseActivity(), MainView.View {

    @Inject lateinit var presenter: MainPresenter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
    }

    override fun onCreatePresenter() {
        presenter.setView(this)
        presenter.onCreate()
    }

    override fun initializeDagger() {
        activityComponent.inject(this)
    }

    override fun showMessage(message : String){
        Toast(...)
    }
}

MainPresenter (Kotlin)

class MainPresenter @Inject constructor(): BasePresenter<MainView.View, MainInteractor>(), MainView.InteractorOutput {

    @Inject lateinit var interactor : MainInteractor

    override fun onCreate() {
        interactor.doSomething()
    }
}

MainInteractor (Kotlin)

class MainInteractor: BaseInteractor() {

    fun doSomething() {
        Log.e("Hello ", "World!")
    }
}

ActivityComponent (Java)

@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class})
public interface ActivityComponent {
    void inject(MainActivity mainActivity);
}

ActivityModule (Java)

@Module
public class ActivityModule {

    private final BaseActivity mActivity;

    public ActivityModule(BaseActivity activity) {
       mActivity = activity;
    }

    @Provides
    @PerActivity
    BaseActivity activity() {
        return mActivity;
    }

    @Provides
    @PerActivity
    MainPresenter provideMainPresenter() {
        return new MainPresenter();
    }
}

ApplicationComponent (Java)

@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {

    void inject(BaseActivity baseActivity);

}

ApplicationModule (Java)

@Module
public class ApplicationModule {

    private final BaseApplication mApplication;

    public ApplicationModule(BaseApplication application) {
        mApplication = application;
    }

    @Provides
    @Singleton
    Context provideApplicationContext() {
        return mApplication;
    }
}

Answer

Currently you have your interactor set up as a field to inject. However there is no mechanism to inject this field and actually there is no need to do this as you should use constructor injection instead.

Remove the following from your presenter:

@Inject lateinit var interactor: MainInteractor

and instead inject it in the constructor:

class MainPresenter @Inject constructor(private val interactor: MainInteractor)

Also currently Dagger has no way of providing a MainInteractor so you need to annotate its constructor with:

class MainInteractor: BaseInteractor @Inject constructor () {

It’s unclear to me what the difference between MainPresenter and MainActivityPresenter is and you may have further issues. These changes should get you closer though.