DEV Community

Cover image for Simplify ViewModelProvider.Factory() Implementation with Kotlin Lambda and Object Expressions
Vincent Tsen
Vincent Tsen

Posted on • Originally published at vtsen.hashnode.dev

Simplify ViewModelProvider.Factory() Implementation with Kotlin Lambda and Object Expressions

Learn how to streamline the implementation of ViewModelProvider.Factory() using Kotlin Lambdas and Object Expressions with examples.

If you are like me and still have not gotten used to the Dependency Injection framework (don't you think it complicates things?), you probably have been implementing the ViewModelProvider.Factory() interface for your view models that has custom constructor parameters.

Multiple ViewModel Factory Classes

class AViewModelFactory(private val repository: ARepository) :
    ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return AViewModel(repository) as T
    }
}
Enter fullscreen mode Exit fullscreen mode

For example, AViewModelFactory is the view model factory class that creates ViewModel which takes in ARepository as a constructor parameter. So what if you have another ViewModel to create? Then, you need to implement another factory class (i.e. BViewModelFactory)

class BViewModelFactory(private val repository: BRepository) :
    ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return BViewModel(repository) as T
    }
}
Enter fullscreen mode Exit fullscreen mode

Well, this seems redundant and can be simplified.

Kotlin Lambda and Object Expressions

You can simply the implementation without explicitly having these factory classes using Kotlin Lambda Functions and Object Expressions as you can see in the following createViewModelFactory() helper function.

fun <VM : ViewModel> createViewModelFactory(createViewModel: () -> VM)
    : ViewModelProvider.Factory {

    return object : ViewModelProvider.Factory {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return createViewModel() as T
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The createViewModel is the lambda where the callers define how they want to create the ViewModel. The return of this function is the implementation of ViewModelProvider.Factory() interface for the ViewModel that you want to create.

So, instead of creating the ViewModel like this:

@Composable()
fun WithoutHelperFunctions() {
    val aViewModel: AViewModel = viewModel(
        factory = AViewModelFactory(ARepository()),
    )

    val bViewModel: AViewModel = viewModel(
        factory = BViewModelFactory(BRepository()),
    )
}
Enter fullscreen mode Exit fullscreen mode

You can create the ViewModel with this createViewModelFactory() helper function:

@Composable()
fun WithHelperFunctions() {
    val aViewModel: AViewModel = viewModel(
        factory = createViewModelFactory {
            AViewModel(ARepository())
        }
    )

    val bViewModel: BViewModel = viewModel(
        factory = createViewModelFactory {
            BViewModel(BRepository())
        }
    )
}
Enter fullscreen mode Exit fullscreen mode

The benefit is, you no longer need to declare multiple factory classes. You just need to have one createViewModelFactory() helper function.

ViewModel Creation Articles

If you're not familiar with ViewModel creations, you may want to visit my following blog posts:

Source Code

GitHub Repository: Demo_ViewModelFactory


Originally published at https://vtsen.hashnode.dev.

Top comments (0)