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;
}
}
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.