https://kotlinlang.org logo
#dagger
Title
# dagger
m

Mehmet

10/30/2023, 5:18 PM
hey all, is it possible to multibind dependencies provided by different components into single injection site? I have Root dagger component and couple of child components root component depends on. Some child components provide the same type of object. In the root component I want to bind all those provided in dependencies into a list/map but dagger doesn’t merge the injections from child components.
Copy code
@Component(
    dependencies = [ChildComponent::class],
    modules = [RootModule::class]
)
interface RootComponent {
    val myClass: MyClass
}

@Module
interface RootModule {
    companion object {
        @[Provides IntoSet]
        fun name(): String = "Root"
    }
}

class MyClass @Inject constructor(names: Set<String>) {
    init {
        //java.lang.AssertionError: names only has [Root]
        assert(names == setOf("Root", "Child")) { "names only has $names" }
    }
I tried below approaches for the child component:
Copy code
//Try 1: Compiles but "Child" is not injected in RootComponent. Which makes sense because "ChildComponent" doesn't expose it.
@Component(modules = [ChildModule::class])
interface ChildComponent {
}

@Module
interface ChildModule {
    companion object {
        @[Provides IntoSet]
        fun name(): String = "Child"
    }
}

//Try 2: compile-time-error: "String cannot be provided without an @Inject constructor or an @Provides-annotated method" It makes sense because there is no provider for `String` type in ChildComponent. IntoSet annotation in ChildModule provides Set<String> type.
@Component(modules = [ChildModule::class])
interface ChildComponent {
    val name: String
}

@Module
interface ChildModule {
    companion object {
        @[Provides IntoSet]
        fun name(): String = "Child"
    }
}

//Try 3: Compile-time-error "[Dagger/DuplicateBindings] Set<String> has incompatible bindings or declarations in RootComponent". Now we have two bindings with type Set<String> one is coming from ChildComponent and the other from RootComponent 
@Component(modules = [ChildModule::class])
interface ChildComponent {
    val names: Set<String>
}

@Module
interface ChildModule {
    companion object {
        @[Provides IntoSet]
        fun name(): String = "Child"
    }
}

// Try 4: Compile time error "@Binds methods can only be present within a @Module or @ProducerModule" 
@Component(modules = [ChildModule::class])
interface ChildComponent {
    @get:[Binds IntoSet]
    val name: String
}

@Module
interface ChildModule {
    companion object {
        @Provides
        fun name(): String = "Child"
    }
}
I’m not sure if what I want is achievable at all. Any help/idea is appreciated.
🧵 2
6 Views