New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Work with Dagger #69
Comments
I settled on the following for now commit I inject the ViewModel.Factory into the Activity, then that to create the VM. Works nicely but we do lose the initial state nice-ness. |
@chrisbanes The reason we moved away from that is because initialState is pretty critical to MvRx. This would prevent a ViewModel from being able to use Fragment args or for MvRx to do proper ViewModel restoration in a new process. Thoughts? |
Yeah, we don't have assisted DI with Dagger so it's hard to get the initialState + fragment args working nicely. I managed to get it sort of working, but I can't rely on I might have a play with AutoFactory and see if I can get it to work. |
Renaming this to be clearer what the goal is (for me anyway). I got AutoFactory working here. The only downside I see is that Can we get a version of |
@chrisbanes have you seen this: https://github.com/square/AssistedInject ? Maybe it'll be helpful in this scenario? |
@mzgreen Ah yes! I've been wanting a reason to try it but totally forgot about it. I'll try on Monday. |
Moving over to https://github.com/square/AssistedInject in chrisbanes/tivi#214 |
@chrisbanes I implemented AssistedInject at Tonal and it's working great! Thank you for putting in that work. I'll try and make a wiki page for it. |
@chrisbanes I was not able to find a way to create a Dagger Here is the ViewModel example; I can't get my head around how I would remove the downcast and keep dagger happy. class MyViewModel @AssistedInject constructor(
@Assisted state: MvRxState,
private val api: Api
) : MvRxViewModel<MyViewModelState>(state as MyViewModelState) {
@AssistedInject.Factory
interface Factory : ViewModelFactory {
override fun create(state: MvRxState): MyViewModel
}
companion object : MvRxViewModelFactory<MyViewModelState> {
@JvmStatic override fun create(
activity: FragmentActivity,
state: MyViewModelState
): BaseMvRxViewModel<MyViewModelState> =
activity.daggerCreate(
factory = MyViewModel.Factory::class.java,
state = state
)
}
} |
@marukami You need to create an |
It would be nice to have |
@chrisbanes Thanks for wrapping your head around all of this, using activities to store the factories works well! Do you have any idea how this might work in a single activity project with multi gradle modules where each feature module only has fragments and therefore no access/ knowledge of the activity? -> ( |
I have been using a fork I made that adds a fragment factory #148. With the fork, you can use the class MyFragment :
BaseMvRxFragment() {
@Inject lateinit var viewModelFactory: MyViewModel.Factory
}
class MyViewModel @AssistedInject constructor(
@Assisted state: MyState,
private val api: TestApi
) : MvRxViewModel<MyState>(state) {
@AssistedInject.Factory
interface Factory : ViewModelFactory<MyState> {
override fun create(state: MyState): MyViewModel
}
companion object : MvRxFragmentViewModelFactory<MyState> {
@JvmStatic override fun create(
fragment: Fragment,
state: MyState
): BaseMvRxViewModel<MyState> =
(fragment as MyFragment).viewModelFactory.create(state)
}
} Any feedback on doing it this way would be awesome. |
Looks good to me, this would really help using MvRx in dagger projects with multiple gradle modules, where not every module has its own activity. Can we merge this @gpeal ? |
Injecting with Dagger #69 is very hard without the Fragment been passed for Fragment ViewModels. So, I added a MvRxFragmentViewModelFactory as another factory type. To keep backward compatibility if the Fragment factory can't be found we can fall back to the Activity factory. If no factory can be found then like before try the single state arg ViewModel constructor before crashing as it would before.
@pwillmann We weren't able to merge that change, unfortunately. You can follow that discussion here. |
However, the tivi app from @chrisbanes was able to use AssistedInject and in our app, we use a MvRxViewModelFactory and manually get the dependencies from the component to do constructor injection. I'm going to close this issue for now since I'm not sure if there is anything actionable at this point. |
At the moment I see no way of integrating with an existing ViewModelProvider.Factory. This is necessary to be able to use Dagger to inject ViewModels.
Example fragment
Is there a way?
The text was updated successfully, but these errors were encountered: