Search code examples
androidkotlindependency-injectiondaggerdagger-hilt

Using multiple @Assisted with same type


I'm using Dagger Assisted in my ViewModel. When I create my ViewModel with a single @Assisted parameter of the same type, it works fine. However, problems arise when there is more than one @Assisted parameter of the same type.

Here is my ViewModel class:

class SampleViewModel @AssistedInject constructor(
    @Assisted val param1: Float,
    @Assisted val param2: Float,
    @Assisted val param3: Float,
) : ViewModel() {

    @AssistedFactory
    interface Factory {
        fun create(
            param1: Float,
            param2: Float,
            param3: Float
        ): SampleViewModel
    }

    companion object {
        fun provideFactory(
            assistedFactory: Factory,
            param1: Float,
            param2: Float,
            param3: Float
        ): ViewModelProvider.Factory = object : ViewModelProvider.Factory {
            @Suppress("UNCHECKED_CAST")
            override fun <T : ViewModel> create(modelClass: Class<T>): T {
                return assistedFactory.create(
                    param1,
                    param2,
                    param3
                ) as T
            }
        }
    }
    
    // .......
}

Here is Fragment:

@AndroidEntryPoint
class SampleFragment : Fragment() {

    @Inject
    lateinit var viewModelAssistedFactory: SampleViewModel.Factory

    override val viewModel: SampleViewModel by viewModels {
        SampleViewModel.provideFactory(
            viewModelAssistedFactory,
            args.param1,
            args.param2,
            args.param3
        )
    }

    // .......
}

The error that occurs for all parameters:

error: @AssistedInject constructor has duplicate @Assisted type: @Assisted float. Consider setting an identifier on the parameter by using @Assisted("identifier") in both the factory and @AssistedInject constructor
    float param1, @dagger.assisted.Assisted
          ^

How can I handle this error?


Solution

  • You can specify @Assisted with keys as follows:

    class SampleViewModel @AssistedInject constructor(
        @Assisted("param1") val param1: Float,
        @Assisted("param2") val param2: Float,
        @Assisted("param3") val param3: Float,
    ) : ViewModel() {
    
        @AssistedFactory
        interface Factory {
            fun create(
                @Assisted("param1") param1: Float,
                @Assisted("param2") param2: Float,
                @Assisted("param3") param3: Float
            ): SampleViewModel
        }
        ...