I'm relatively new to Dagger and I just started to use Hilt. What I want is to inject an application-wide repository (meaning it needs to be the same object everywhere) into a ViewModel
. The repository will be used to retrieve the user, auth token and stuff like that. This is the closest I could get:
@Module
@InstallIn(ApplicationComponent::class)
abstract class ApplicationModule {
@Singleton
@Binds
abstract fun bindUserService(
userRepository: UserRepository
): UserService
}
@Singleton
class UserRepository @Inject constructor(
) : UserService {
private var _user: User? = null
override fun getUser(): Observable<User> {
return if (_user == null) {
fetchUser()
} else {
Observable.just(_user)
}
}
private fun fetchUser(): Observable<User> {
return Observable.just(User("foo", Random.nextDouble(100.00)))
.delay(2, TimeUnit.SECONDS)
.doOnEach { _user = it.value }
}
}
class ProfileViewModel @ViewModelInject constructor(
private val userService: UserService,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
val user: MutableLiveData<User> by lazy {
MutableLiveData<User>()
}
fun init() {
userService.getUser().observeOn(AndroidSchedulers.mainThread()).subscribe { user.apply { value = it } }
}
}
this way everything works fine, using debug I can confirm that every time the ViewModel
is used the same instance of UserRepository
is injected. The problem is that _user
is null
the second time (eg. view is destroyed and re-created) getUser()
is called. I don't know if I'm doing some silly mistake on the kotlin-side or a silly mistake on the Hilt-side.
any idea what's going on?
In your case doOnEach
call when onSuccess
and onComplete
it means it call 2 times, and second time it.value
is null and _user
asign to null
again. It's not bug from Hilt
private fun fetchUser(): Observable<User> {
return Observable.just(User("foo", Random.nextDouble(100.00)))
.delay(2, TimeUnit.SECONDS)
.doOnEach { _user = it.value }
}