Implement ViewModelProvider.Factory Interface for Custom ViewModel / AndroidViewModel Factory Creation
Tags: android, beginners, kotlin
Published: 2021-11-20 01:08:47

**We do NOT need to extend ViewModelProvider.NewInstanceFactory (for ViewModel) or ViewModelProvider.AndroidViewModel (for AndroidViewModel)**

In my previous post -  [Recommended Ways To Create ViewModel or AndroidViewModel](https://vtsen.hashnode.dev/recommended-ways-to-create-viewmodel-or-androidviewmodel), I mentioned that in order to create `ViewModel`, we need to create a factory that extends `ViewModelProvider.NewInstanceFactory()` and to create `AndroidViewModel`, we need to extend `ViewModelProvider.AndroidViewModelFactory()`. 

Well, it works, but it is **unnecessary**. We can just implement the `ViewModelPrvoider.Factory` interface directly for both of them.

### ViewModelProvider.NewInstanceFactory()
```kotlin
class MyViewModelFactory(private val repository: Repository)
    : ViewModelProvider.NewInstanceFactory() {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
            return MyViewModel(repository) as T
        }

        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
```

### Can be replaced by ViewModelProvider.Factory
```kotlin
class MyViewModelFactory(private val repository: Repository)
    : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
            return MyViewModel(repository) as T
        }

        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
```


### ViewModelProvider.AndroidViewModelFactory(app)
```kotlin
class MyAndroidViewModelFactory(
    private val app: Application,
    private val repository: Repository)
    : ViewModelProvider.AndroidViewModelFactory(app) {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        if (modelClass.isAssignableFrom(
                MyAndroidViewModel::class.java)) {

            return MyAndroidViewModel(app, repository) as T
        }

        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
```
### Can be replaced by ViewModelProvider.Factory

```kotlin
class MyAndroidViewModelFactory(
    private val app: Application,
    private val repository: Repository)
    : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        if (modelClass.isAssignableFrom(
                MyAndroidViewModel::class.java)) {

            return MyAndroidViewModel(app, repository) as T
        }

        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
```

Since both `ViewModelProvider.NewInstanceFactory()`and `ViewModelProvider.AndroidViewModelFactory()` implement`ViewModelPrvoider.Factory` interface, we can just implement the `ViewModelPrvoider.Factory` interface directly to create the custom `ViewModel` / `AndroidViewModel` factory which takes in different constructor parameters. We don't need an additional layer here.

![Implement_ViewModelProvider_Factory_Interface_01.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1635508822346/WxUdoQBQN.jpeg)

By the way, this is the feedback that I get from **medium** suggesting another better approach is to use **Hilt Dependency Injection** instead of using factory to create the custom `ViewModel`, which is also known as **constructor dependency injection**.

I personally have not used Hilt yet, and will definitely learn and blog about it.

> **[Updated - July 04, 2022]:** I have played around with Hilt a bit and here are the simple steps to implement Hilt into your app.
- [How to Implement Hilt in Android App?](https://vtsen.hashnode.dev/how-to-implement-hilt-in-android-app)
- [Convert View Model to Use Hilt Dependency Injection](https://vtsen.hashnode.dev/convert-view-model-to-use-hilt-dependency-injection)

---

*Originally published at [https://vtsen.hashnode.dev](https://vtsen.hashnode.dev/implement-viewmodelproviderfactory-interface-for-custom-viewmodel-androidviewmodel-factory-creation)*.