Have your ever need to pass some additional parameter into your Viewmodel? But wait, your viewmodel have already some injections? So how can you do this ?
Behold Assisted Injection!
Here is the main usage. As you can see on the right preview, we have two viewmodel and the second one needs some id of previous selected data. But the second viewmodel has already constructor injections like below.
class MainDetailViewModel @Inject constructor(
private val service: Service
) : ViewModel() {
//Some magic works here
}
So how can we do this? Because if we pass the parameter in constructor of viewmodel, the constructor injection magic will be pointless and force us to make much boilerplate code.
AssistedInject annotations helps us to pass some additional parameters with already constructor injections we did before. Here is the usage,
class MainDetailViewModel @AssistedInject constructor(
private val service: Service,
@Assisted val civilizationId: Int //Magic here :)
) : ViewModel() {
@AssistedInject.Factory
interface Factory {
fun create(civilizationId: Int): MainDetailViewModel
}
// Some magic works here
}
If we will use this parameter that we passed via @Assisted, we must provide this as usual. Here is the sample usage,
//Our id comes from intent here
private val mainDetailViewModel by viewModel(this) {
injector.mainDetailViewModelFactory.create(
intent.getIntExtra(getString(R.string.selected_civilization), -1))
}
As far as I tried, in multi-module project, for example you have some presentation layer that contains your Viewmodels, because of your @AssistedInject.Factory is generated in your Presentation module and you want to use in UI module which is your main layer, Dagger2 can not access that factory class which is generated in other module. I still search the solution. If you know the problem or you have any questions, hit me on Twitter
If you have Viewmodels that have already use constructor injection and you need to pass additional parameter through them, Assisted Injection is all you ever need. Please have a look! If you have any question why we need to pass the parameter via constructor, please try to rotate your phone and you will see you make network request again. Because you should make your request in your ViewModel's init function.
If you have any questions, hit me on Twitter
Copyright 2019 Tayfun CESUR
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.