``` class DetailViewModelFactory(private val id: I...
# dagger
s
Copy code
class DetailViewModelFactory(private val id: Int) : ViewModelProvider.Factory {
    private val movieRepository: MovieRepository = Injector.getAppComponent().getMovieRepository()
I was wondering if this piece of code could be rewritten in primary and secondary constructor form where
MovieRepository
injected via Dagger 2. (Code:- https://github.com/sudhirkhanger/Genius)
g
And what is your problem with this?
s
There is no problem with this code. I was just curious if there was a better way (Kotlin way) that I wasn't aware of.
g
No, I mean to have additional constructor in Kotlin
Do you aware of secondary constructor feature? https://kotlinlang.org/docs/reference/classes.html
s
Yes, I understand the concept of secondary constructor. I need to inject
MovieRepository
via Dagger 2 and provide
id: Int
when the class is initialized. If I declare
MovieRepository
in the primary constructor then I don't have any access to it in the secondary constructor to pass on to the primary. If I declare id in the primary constructor then my secondary constructor will contain both
MovieRepository
and
id: Int
but then I don't want to provide
MovieRepository
from where I will initialize
DetailViewModelFactory
class. So I guess above should be fine. Unless there is a way where I can inject only one parameter via Dagger 2 out of several and when I initialize the class I only have to provide the id.
g
And and you canniot inject id from dagger?
If so, you need a factory, you inject factory first and than call
create(id)
s
I can't inject id because it is provided by the user and not create via some object graph. And this is a Factory class itself so I probably don't want to create another Factory class to create the factory class. I suppose my setup is fine.
g
Factory or factories is very enterprise solution tho 😅
Looks strange, I agree, but still kinda fine in this caee
d
@Sudhir Singh Khanger - check out assisted injection. Your use case sounds ideal. https://github.com/square/AssistedInject#assisted-injection-for-jsr-330
g
Yes, but it will be Factory for Factory %)
d
yea 😬
Copy code
class @AssistedInject DetailViewModelFactory(
	@Assisted private val id: Int, // Your runtime state
	private val repo: MovieRepository) : ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(DetailViewModel::class.java))
            @Suppress("UNCHECKED_CAST")
            return DetailViewModel(repo, id) as T
        throw IllegalArgumentException("Unknown ViewModel class")
    }

	// Instructions to Dagger for code-gen
    @AssistedInject.Factory
  	interface Factory {
    	fun create(id: Int): DetailViewModelFactory
  }
}
Just hand wrote this. Not sure if it’s 100%. I use the subcomponent route at present rather than AssistedInject for injecting runtime state