I have a component and a subcomponent that contribute elements to a single set. When using @Provides and @IntoSet, my component and subcomponent are returning all the expected elements. The following test shows that the subcomponent collects the elements that are provided in the component and the subcomponent:
public class ComponentTestsWithProvides {
@Test
public void testStringSet() {
final TestComponent component = DaggerComponentTestsWithProvides_TestComponent.builder()
.testComponentModule(new TestComponentModule())
.build();
final TestSubcomponent subcomponent = component.getTestSubcomponent(new TestSubcomponentModule());
assertThat(component.getStrings())
.containsOnly("Component");
assertThat(subcomponent.getStrings())
.containsOnly("Component", "Subcomponent");
}
@Qualifier
public @interface ComponentQualifier {}
@Component(modules = TestComponentModule.class)
public interface TestComponent {
Set<String> getStrings();
TestSubcomponent getTestSubcomponent(TestSubcomponentModule module);
}
@Module
public class TestComponentModule {
@Provides
@ComponentQualifier
String provideString() {
return "Component";
}
@Provides
@IntoSet
String provideStringIntoSet(@ComponentQualifier String string) {
return string;
}
}
@Qualifier
public @interface SubcomponentQualifier {}
@Subcomponent(modules = TestSubcomponentModule.class)
public interface TestSubcomponent {
Set<String> getStrings();
}
@Module
public class TestSubcomponentModule {
@Provides
@SubcomponentQualifier
String provideString() {
return "Subcomponent";
}
@Provides
@IntoSet
String provideStringIntoSet(@SubcomponentQualifier String string) {
return string;
}
}
}
Since the elements are provided by existing providers, I'd like to use @Binds instead of @Provides. The following code should have equivalent behavior, since it just replaces @Provides with @Binds:
public class ComponentTestsWithBinds {
@Test
public void testStringSet() {
final TestComponent component = DaggerComponentTestsWithBinds_TestComponent.builder()
.testComponentModule(new TestComponentModule())
.build();
final TestSubcomponent subcomponent = component.getTestSubcomponent(new TestSubcomponentModule());
assertThat(component.getStrings())
.containsOnly("Component");
assertThat(subcomponent.getStrings())
.containsOnly("Component", "Subcomponent");
}
@Qualifier
public @interface ComponentQualifier {}
@Component(modules = TestComponentModule.class)
public interface TestComponent {
Set<String> getStrings();
TestSubcomponent getTestSubcomponent(TestSubcomponentModule module);
}
@Module(includes = TestComponentModule.Bindings.class)
public static class TestComponentModule {
@Provides
@ComponentQualifier
String provideString() {
return "Component";
}
@Module
public interface Bindings {
@Binds
@IntoSet
String provideStringIntoSet(@ComponentQualifier String string);
}
}
@Qualifier
public @interface SubcomponentQualifier {}
@Subcomponent(modules = TestSubcomponentModule.class)
public interface TestSubcomponent {
Set<String> getStrings();
}
@Module(includes = TestSubcomponentModule.Bindings.class)
public static class TestSubcomponentModule {
@Provides
@SubcomponentQualifier
String provideString() {
return "Subcomponent";
}
@Module
public interface Bindings {
@Binds
@IntoSet
String provideStringIntoSet(@SubcomponentQualifier String string);
}
}
}
However, the subcomponent only returns "Component". Indeed, the implementation of TestSubcomponent.getStrings() does not use the subcomponent string provider:
public Set<String> getStrings() {
return DaggerComponentTestsWithBinds_TestComponent.this.setOfStringProvider.get();
}
When using @Provides instead of @Binds, TestSubcomponent.getStrings() has the expected implementation:
private void initialize() {
this.provideStringProvider =
ComponentTestsWithProvides_TestSubcomponentModule_ProvideStringFactory.create(
testSubcomponentModule);
this.provideStringIntoSetProvider =
ComponentTestsWithProvides_TestSubcomponentModule_ProvideStringIntoSetFactory.create(
testSubcomponentModule, provideStringProvider);
this.setOfStringProvider =
SetFactory.<String>builder(2, 0)
.addProvider(
DaggerComponentTestsWithProvides_TestComponent.this.provideStringIntoSetProvider)
.addProvider(provideStringIntoSetProvider)
.build();
}
@Override
public Set<String> getStrings() {
return setOfStringProvider.get();
}
}
Ah, good find. We're not detecting that as a subcomponent with local multibinding contributions. Thanks for alerting us, hope to have a fix soon!
I have a request out for review, should definitely be synced out for Dagger 2.6 (or maybe even 2.5.1)
Ah, awesome, that was fast! :)
On Thu, Jun 23, 2016 at 3:30 PM, Ron Shapiro [email protected]
wrote:
I have a request out for review, should definitely be synced out for
Dagger 2.6 (or maybe even 2.5.1)—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/google/dagger/issues/401#issuecomment-228205301, or mute
the thread
https://github.com/notifications/unsubscribe/ACZo0G8Eu9vnkRqJkUcej-yDi6M4iYaMks5qOwkggaJpZM4I8XGP
.
Most helpful comment
Ah, good find. We're not detecting that as a subcomponent with local multibinding contributions. Thanks for alerting us, hope to have a fix soon!