Multibinding¶
Table of Contents¶
- Overview
- Contributing to a Set
- Combining with @AutoBinds
- Choosing a component
- Selecting specific binding targets
- Generated code
Overview¶
Use @AutoBindsIntoSet to contribute a class into a Dagger multibinding Set
of each direct supertype (implemented interfaces and extended parent classes).
This lets you collect multiple implementations automatically without maintaining
a manual module.
Contributing to a Set¶
Annotate each implementation with @AutoBindsIntoSet:
@AutoBindsIntoSet
class LoggingInterceptor @Inject constructor() : Interceptor {
override fun intercept(chain: Chain): Response { /* ... */ }
}
@AutoBindsIntoSet
class AuthInterceptor @Inject constructor() : Interceptor {
override fun intercept(chain: Chain): Response { /* ... */ }
}
Now you can inject Set<Interceptor> anywhere and Hilt will collect all
contributions automatically:
class ApiClient @Inject constructor(
private val interceptors: Set<@JvmSuppressWildcards Interceptor>,
) {
// interceptors contains LoggingInterceptor and AuthInterceptor
}
Combining with @AutoBinds¶
@AutoBindsIntoSet can be combined with @AutoBinds on the same class to
produce both a direct binding and a set contribution:
@AutoBinds // provides Interceptor directly
@AutoBindsIntoSet // also contributes to Set<Interceptor>
class DefaultInterceptor @Inject constructor() : Interceptor { /* ... */ }
This generates two separate modules with different names to avoid conflicts.
Choosing a Component¶
@AutoBindsIntoSet supports the same installIn parameter as @AutoBinds.
It defaults to HiltComponent.Unspecified with auto-detection from scope
annotations:
@ActivityScoped
@AutoBindsIntoSet // installed in ActivityComponent (auto-detected)
class ActivityInterceptor @Inject constructor() : Interceptor { /* ... */ }
@AutoBindsIntoSet(installIn = HiltComponent.ViewModel)
class ViewModelInterceptor @Inject constructor() : Interceptor { /* ... */ }
See Scopes and Components for the full reference.
Selecting Specific Binding Targets¶
By default, @AutoBindsIntoSet contributes the class to a Set of every
direct supertype. Use bindTo to restrict which supertypes are included or to
target a grandparent:
interface BaseHandler
open class AbstractHandler : BaseHandler
// Contributes to Set<BaseHandler> only, skipping AbstractHandler
@AutoBindsIntoSet(bindTo = [BaseHandler::class])
class MyHandler @Inject constructor() : AbstractHandler()
bindTo accepts any transitive supertype. An error is emitted at compile time
if a listed type is not a supertype of the annotated class.
Generated Code¶
For each annotated class, the processor generates an interface Hilt module
with @Binds @IntoSet functions:
@Module
@InstallIn(SingletonComponent::class)
internal interface LoggingInterceptor__IntoSetModule {
@Binds @IntoSet
fun bindToInterceptor(impl: LoggingInterceptor): Interceptor
}
The same class requirements as basic usage
apply: the class must be concrete, non-abstract, not an inner class, have @Inject on its
primary constructor, and implement at least one interface or extend a parent class.