Meghanath Ganji
Meghanath Ganji

Reputation: 41

Dagger 2 Kotlin - @Named qualifier for @Binds method

I wanted to have @Named qualifier for object that's returned from @Binds method, but I noticed that's only possible through static provides method, which I couldn't figure out in practical implementation. So below is what I wanted to achieve.

I have a custom UserScope, which would contain all activities/fragments/viewModels after user logged in, I have LoginViewModel in AuthViewModelModule and LeadViewModel an other VM in UserViewModelModule both VMModule binds VMProvider.Factory and for that reason I need to have @Named qualifier for the VMFactory instance, so I could inject @Named ones in respective activities/fragments.

@Module
internal abstract class AuthViewModelModule {

    @Binds
    @IntoMap
    @ViewModelKey(LoginViewModel::class)
    internal abstract fun bindLoginViewModel(loginViewModel: LoginViewModel): ViewModel

    @Binds
    internal abstract fun bindViewModelFactory(factory: AuthViewModelFactory):
        ViewModelProvider.Factory
}

@Module
internal abstract class UserViewModelModule {

    @Binds
    @IntoMap
    @ViewModelKey(LeadViewModel::class)
    internal abstract fun bindLeadViewModel(leadViewModel: LeadViewModel): ViewModel

    @Binds
    internal abstract fun bindViewModelFactory(factory: UserViewModelFactory):
        ViewModelProvider.Factory
}

Upvotes: 3

Views: 2529

Answers (2)

Luiz Filipe Medeira
Luiz Filipe Medeira

Reputation: 1320

You can inject a @Named into a kotlin activity like this:

@JvmField
@Inject
@field:Named("PARAMETER_NAME")
var something: Boolean = false

or like this for non primitive values:

@JvmField
@Inject
@field:Named("PARAMETER_NAME")
lateinit var something: SomeType

Upvotes: 0

Benjamin
Benjamin

Reputation: 7368

Add a qualifier to your provider methods:

@Binds
@Named("Auth")
internal abstract fun bindViewModelFactory(factory: AuthViewModelFactory): ViewModelProvider.Factory

@Binds
@Named("User")
internal abstract fun bindViewModelFactory(factory: UserViewModelFactory): ViewModelProvider.Factory

And here is the tricky part: when injecting, you have to use the following syntax:

@Inject
@field:Named("Auth")
internal lateinit var factory: ViewModelProvider.Factory

@Inject
@field:Named("User")
internal lateinit var factory: ViewModelProvider.Factory

Upvotes: 6

Related Questions