Support for set multibindings with component provision methods of component dependencies
See original GitHub issueDagger documentation says that:
The following are available as dependencies and may be used to generate a well-formed component:
- The component provision methods of the component dependencies
And also that:
A binding in a subcomponent can depend on a multibound set or map from its parent, just as it can depend on any other binding from its parent. But a subcomponent can add elements to multibound sets or maps that are bound in its parent as well, by simply including the appropriate
@Provides
methods in its modules.
Would it be possible to add support for multibindings from component dependencies?
I suppose there is no support for that right now, I tried:
@Component(modules = [ModuleA::class])
interface ParentA {
@ElementsIntoSet
fun strings(): Set<String>
}
@Module
class ModuleA {
@Provides
@IntoSet
fun string() = "A"
}
@Component(modules = [ModuleB::class])
interface ParentB {
@ElementsIntoSet
fun strings(): Set<String>
}
@Module
class ModuleB {
@Provides
@IntoSet
fun string() = "B"
}
@Component(dependencies = [ParentA::class, ParentB::class])
interface Child {
val strings: Set<String>
}
But I get this error:
e: com/example/dagger/ParentB.java:10: error: Multibinding annotations may only be on @Provides, @Produces, or @Binds methods
@dagger.multibindings.ElementsIntoSet()
^
e: com/example/dagger/ParentA.java:10: error: Multibinding annotations may only be on @Provides, @Produces, or @Binds methods
@dagger.multibindings.ElementsIntoSet()
^
e: com/example/dagger/Child.java:10: error: [Dagger/DuplicateBindings] java.util.Set<java.lang.String> is bound multiple times:
public abstract java.util.Set<java.lang.String> getStrings();
^
@org.jetbrains.annotations.NotNull @dagger.multibindings.ElementsIntoSet Set<String> com.example.dagger.ParentA.strings()
@org.jetbrains.annotations.NotNull @dagger.multibindings.ElementsIntoSet Set<String> com.example.dagger.ParentB.strings()
java.util.Set<java.lang.String> is provided at
com.example.dagger.Child.getStrings()
My use case is that I have an interface like AccountRepository
and it’s implemented differently in two components. I need a component that uses both AccountRepository
implementations to get all accounts from both of them.
I was trying to achieve something similar by using modules directly instead, but there were some scoping issues I wasn’t able to resolve.
Update
After some more experimenting, this idea might not be that useful after all. If ParentA
and ParentB
have other provision methods with overlapping types, I wouldn’t be able to set them both as dependencies anyway… But maybe in some other scenario this would be useful.
Issue Analytics
- State:
- Created 5 years ago
- Comments:5
Top GitHub Comments
@ronshapiro Can you please clarify how #1112 would solve this? Would I have to write e.g.
where
includeElementsFromSet
would have@ElementsIntoSet
annotation, is that correct?I’m curious because we still need to add the child component. Plus if we want to provide more than one multibinding we’ll have something like:
So for each component we’ll have to both add it to the root component and specify each multibinding provision separately. Seems like it would be pretty annoying, since we now need to capture the child component in a variable and be sure to explicitly add each multibinding provision (even though it’s already defined in the component). Any thoughts on this?
I’m interested in seeing this as well - #1112 doesn’t solve this because even in @lwasyl’s example, if there are two child components that both provide the same set, the parent can’t be constructed due to conflicting bindings of the same set type.