Tried to solve this reading the docs, and also I followed this example. But I did not succeed. So I would need to find out what am I missing or doing wrong.
I have an app module, where the @HiltAndroidApp
stands:
@HiltAndroidApp
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
...
}
}
Now I have a :core module where I have my FirebaseAuth
dependency generated from a module:
@Module
@InstallIn(ApplicationComponent::class)
class FirebaseModule{
@Provides
fun provideFirebaseAuth() : FirebaseAuth = FirebaseAuth.getInstance()
}
And a :login
module, in which I am stuck.
Before continuing: :app
module implements :core
and :login
modules.
Now I have created a LoginModuleDependencies
in :core
:
@EntryPoint
@InstallIn(ApplicationComponent::class)
interface LoginModuleDependencies {
fun firebaseAuth(): FirebaseAuth
}
So I assume this one is used in order to expose the dependencies across dynamic features.
Jumping to the LoginComponent
(in the ':login' module), I do this:
@Component(dependencies = [LoginModuleDependencies::class])
interface LoginComponent {
fun inject(loginFragment: LoginFragment)
@Component.Factory
interface Factory {
fun create(
loginModuleDependencies: LoginModuleDependencies
): LoginComponent
}
}
Which according to the docs, allows me to do this:
@OptIn(ExperimentalCoroutinesApi::class)
class LoginFragment : Fragment(R.layout.fragment_login) {
private val loginViewModel: LoginViewModel by viewModels()
private var fragmentLoginBinding: FragmentLoginBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
DaggerLoginComponent.factory()
.create(
loginModuleDependencies = EntryPointAccessors.fromApplication(
requireActivity().applicationContext,
LoginModuleDependencies::class.java
)
).inject(this)
super.onCreate(savedInstanceState)
}
...
}
The crash: RuntimeException: Cannot create an instance of class com.coroutinedispatcher.login.LoginViewModel
Following the logs a little bit further:
Caused by: java.lang.InstantiationException: java.lang.Class<com.coroutinedispatcher.login.LoginViewModel> has no zero argument constructor
This is what assume that I am either missing something, or doing something wrong.
Because my LoginViewModel
looks like this:
class LoginViewModel @ViewModelInject constructor(private val firebaseAuth: FirebaseAuth, @Assisted private val savedStateHandle: SavedStateHandle) : ViewModel()
I can verify that if I do field injection in the respective fragment, the FirebaseAuth
instance is retrieved.
So, what I am currently doing wrong?
EDIT: So basically, I was able to confirm that I can pull from ApplicationComponent
because doing this:
@Inject lateinit var firebaseAuth: FirebaseAuth
// onViewCreated
Log.d(someClassName, "value: ${::firebaseAuth.isInitialized}") // true
And also, creating a new normal class that pulls that dep, works:
class SomeWeirdClass @Inject constructor(private val firebaseAuth: FirebaseAuth)
Logging that on the Fragment
Log.d(someClassName, "value: ${::someWeirdClass.isInitialized}") // true
So I assume there might be a versioning problem, but I just cannot find out what. Providing a ViewModelProvider.Factory
works, but what's the point in using it if you are supposed to use @ViewModelInject
.