An android library to implment dagger with android architecture ViewModel component.
This library enables you to easily provide ViewModels with their dependencies and inject a view model factory into a Fragment or Activity.
This android library simply reduces the boilerplate of implmenting dagger with android architecture ViewModel component inspired by the google github sample
The default ViewModel Provider doesn’t allow for constructor inection
So we have to create a ```ViewModelProvider.Factory``` that can provide the dependencies. However this is non-trivial and requires some boilerplate to do cleanly with dagger.
### Solution
Using daggers multibing we can create a map with the ViewModels and a generic ```ViewModelProvider.Factory``` that can be injected into the Activity or Fragment which can be used the to get the desired ```ViewModel
Ensure you have the jcentre() dependencies in your root build.gradle (most android projects should have this by default)
allprojects {
repositories {
...
jcenter()
}
}
Add the dependency in the build.gradle of any app or module.
dependencies {
implementation 'com.github.arranlomas.daggerviewmodelhelper:daggerviewmodelhelper:0.1.0'
}
(See the sample app for full details)
Main Application
class Application : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
AppInjector.init(this)
val appComponent = DaggerAppComponent.create()
appComponent.inject(this)
return appComponent
}
}
ViewModelModule
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(MainViewModel::class)
abstract fun bindMainViewModel(mainViewModel: MainViewModel): ViewModel
//IMPORTANT - this is the generic ViewModelFactory supplied with this library that created the ViewModel with its dependencies
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
ViewModel
IMPORATANT - note the @Inject constructor with the dependencies
class MainViewModel @Inject constructor(private val someDependency: ISomeDependency) : ViewModel() {
fun getSomeStuff(): LiveData<List<Int>> {
return someDependency.getSomeStuff()
}
}
Activity
IMPORTANT - note how the view model factory is injeccted and how it implements Injectable (this is so we don’t have to call AndroidInjection.inject(this) just like with DaggerActivity but DaggerActivity cannot be used with ViewModelProvider
class MainActivity : AppCompatActivity(), Injectable {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val viewModel = ViewModelProviders.of(this, viewModelFactory).get(MainViewModel::class.java)
viewModel.getSomeStuff().observe(this, Observer<List<Int>> { somewhereToShowStuff.text = it?.toString() ?: "error" })
}
}