0

My application has DI. It includes a RoomModule and RoomComponent.

RoomModule.kt

@Module
class RoomModule(private val app: Application) {

  val localDatabase: LocalDatabase = Room
        .databaseBuilder(app, LocalDatabase::class.java, "local-db")
        .build()

  @Provides
  @Singleton
  internal fun providesApplication(): Application {
    return app
  }

  @Singleton
  @Provides
  internal fun providesRoomDatabase(): LocalDatabase {
    return localDatabase
  }

  @Singleton
  @Provides
  internal fun providesUserDao(localDatabase: LocalDatabase): UserDao {
    return localDatabase.getUserDao()
  }

  @Singleton
  @Provides
  internal fun providesUserRepo(userDao: UserDao): UserRepo {
    return UserDataSource(userDao)
  }

}

RoomComponent.kt

@Singleton
@Component(dependencies = [], modules = [RoomModule::class])
interface RoomComponent {
    fun userDao(): UserDao

    fun localDatabase(): LocalDatabase

    fun userRepo(): UserRepo
}

To create a RoomDatabase I need an App Therefore, I do the following in my first activity.

MyActivity.java

public class MyActivity extends MvpAppCompatActivity {

  @Inject
  Interactor interactor;

  @InjectPresenter
  Presenter presenter;

  @ProvidePresenter
  Presenter providePresenter(){
    DaggerAppComponent.builder()
            .build()
            .inject(this);

    return new Presenter(interactor);
  }

 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.myactivity);


    DaggerRoomComponent.builder()
            .roomModule(new RoomModule(getApplication()))
            .build();

    ...

    presenter.someMethod();
  }

  ...

Next, this activity calls the method in Presentor. Presentor calls a method in Interactor, where I want to inject RoomDatabase.

Presentor.kt

@InjectViewState
class Presenter(val interactor: 
Interactor): MvpPresenter<MyView>(){

fun someMethod(){
    if (interactor.getUser() != null) {
       // TODO smth...
    }
}
...

Interactor.kt

@Inject
lateinit var userRepo: UserRepo  //null

override fun getUser(): User? {
    // Using userRepo
}

But the variable is null.

The problem is that in the class where I need the database there is no Context, which is necessary to create it. Look at the visualization of my problem

I implemented the code described in this answer Dagger2 Inject class with parameter (using Room)

MaxAstin
  • 463
  • 5
  • 14
  • _But the variable is null._ This sounds like you're creating the object but not injecting it, [see here](https://stackoverflow.com/q/50270375/1837367) for some general information. If you can't figure it out please include more information about your setup in your question – David Medenjak Oct 09 '19 at 21:03
  • I have included more information – MaxAstin Oct 11 '19 at 18:38

1 Answers1

1

This code is control about your instance.

@Singleton
  @Provides
  internal fun providesRoomDatabase(): LocalDatabase {
    return localDatabase
  }

to create an instance and make it injectable you should provide it through providesRoomDatabase, like this:

  @Singleton
  @Provides
  internal fun providesRoomDatabase(): LocalDatabase {
     val localDatabase: LocalDatabase = Room
        .databaseBuilder(app, LocalDatabase::class.java, "local-db")
        .build()
    return localDatabase
  }
Amjad Alwareh
  • 2,926
  • 22
  • 27
  • The problem is that for this I need an app, which there is only in activity. but I need the database in Interctor class. – MaxAstin Oct 10 '19 at 13:41