title: Why a viewmodel factory is needed in Android?
body: <p>We have been discussing about this but we don't know the reason of creating a viewmodel factory to create a viewmodel instead of instantiate the viewmodel directly. What is the gain of creating a factory that just creates the viewmodel?</p>
  
  <p>I just put a simple example of how I did it without Factory</p>
  
  <p>here is the kodein module:</p>
  
  <pre><code>val heroesRepositoryModel = Kodein {
      bind&lt;HeroesRepository&gt;() with singleton {
          HeroesRepository()
      }
  
      bind&lt;ApiDataSource&gt;() with singleton {
          DataModule.create()
      }
  
      bind&lt;MainViewModel&gt;() with provider {
          MainViewModel()
      }
  }
  </code></pre>
  
  <p>The piece of the Activity where I instantiate the viewmodel without using the factory </p>
  
  <pre><code>class MainActivity : AppCompatActivity() {
      private lateinit var heroesAdapter: HeroAdapter
      private lateinit var viewModel: MainViewModel
      private val heroesList = mutableListOf&lt;Heroes.MapHero&gt;()
      private var page = 0
      private var progressBarUpdated = false
  
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
          viewModel = ViewModelProviders.of(this)
                  .get(MainViewModel::class.java)
          initAdapter()
          initObserver()
          findHeroes()
      }
  </code></pre>
  
  <p>The ViewModel where I instantiate the usecase directly without having it in the constructor</p>
  
  <pre><code>class MainViewModel : ViewModel(), CoroutineScope {
  
      private val heroesRepository: HeroesRepository = heroesRepositoryModel.instance()
      val data = MutableLiveData&lt;List&lt;Heroes.MapHero&gt;&gt;()
  
      private var job: Job = Job()
      override val coroutineContext: CoroutineContext
          get() = uiContext + job
  
      fun getHeroesFromRepository(page: Int) {
          launch {
              try {
                  val response = heroesRepository.getHeroes(page).await()
                  data.value = response.data.results.map { it.convertToMapHero() }
              } catch (e: HttpException) {
                  data.value = null
              } catch (e: Throwable) {
                  data.value = null
              }
          }
      }
  
      override fun onCleared() {
          super.onCleared()
          job.cancel()
      }
  }
  </code></pre>
  
  <p>So here a example using factory</p>
  
  <pre><code>class ListFragment : Fragment(), KodeinAware, ContactsAdapter.OnContactListener {
  
      override val kodein by closestKodein()
  
      private lateinit var adapterContacts: ContactsAdapter
  
      private val mainViewModelFactory: MainViewModelFactory by instance()
      private val mainViewModel: MainViewModel by lazy {
          activity?.run {
              ViewModelProviders.of(this, mainViewModelFactory)
                  .get(MainViewModel::class.java)
          } ?: throw Exception("Invalid Activity")
      }
  
      override fun onCreateView(
              inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
          return inflater.inflate(R.layout.fragment_list, container, false)
      }
  </code></pre>
  
  <p>The viewmodelfactory:</p>
  
  <pre><code>class MainViewModelFactory (private val getContacts: GetContacts) : ViewModelProvider.Factory {
  
      override fun &lt;T : ViewModel?&gt; create(modelClass: Class&lt;T&gt;): T {
          if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
              return MainViewModel(getContacts) as T
          }
          throw IllegalArgumentException("Unknown ViewModel class")
      }
  }
  </code></pre>
  
  <p>And the viewmodel:</p>
  
  <pre><code>class MainViewModel(private val getContacts: GetContacts) : BaseViewModel() {
      lateinit var gamesList: LiveData&lt;PagedList&lt;Contact&gt;&gt;
      var contactsSelectedData: MutableLiveData&lt;List&lt;Contact&gt;&gt; = MutableLiveData()
      var contactsSelected: ArrayList&lt;Contact&gt; = ArrayList()
      private val pagedListConfig by lazy {
          PagedList.Config.Builder()
                  .setEnablePlaceholders(false)
                  .setInitialLoadSizeHint(PAGES_CONTACTS_SIZE)
                  .setPageSize(PAGES_CONTACTS_SIZE)
                  .setPrefetchDistance(PAGES_CONTACTS_SIZE*2)
                  .build()
      }
  </code></pre>
  
  <p>Here is the complete first example:</p>
  
  <p><a href="https://github.com/ibanarriolaIT/Marvel/tree/mvvm" rel="noreferrer">https://github.com/ibanarriolaIT/Marvel/tree/mvvm</a></p>
  
  <p>And the complete second example:</p>
  
  <p><a href="https://github.com/AdrianMeizoso/Payment-App" rel="noreferrer">https://github.com/AdrianMeizoso/Payment-App</a></p>