AssistedInjection

Introduction: Dagger Assisted Injection Sample with Age of Empires API
More: Author   ReportBugs   
Tags:

      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!

Main use case of 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.

Assisted Inject Constructor

       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
}

Providing the factory

       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))  
}

Keynotes

Usage in Multi-module project

       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

Core Libraries

Summary

       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.

Greetings

If you have any questions, hit me on Twitter

Licence

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.
Apps
About Me
Google+: Trinea trinea
GitHub: Trinea