trevjonez / Dagger2-MultiBinding-Android-Example

An attempt to create an example of the ideas shown in this video https://youtu.be/iwjXqRlEevg
Apache License 2.0
21 stars 1 forks source link

Adding Module to ActivityComponent #2

Closed jemshit closed 7 years ago

jemshit commented 7 years ago

How do we add Module to ActivityComponent? Like some ActivityComponent needs ActivityModule, but some does not (like on this repo)

trevjonez commented 7 years ago

You just add it to the ActivityComponent then add a method to set it on the builder class

@Subcomponent(modules = {MainActivityModule.class})
@MainActivityScope
public interface MainActivityComponent extends PlainComponent<MainActivity> {

    @Subcomponent.Builder
    interface Builder extends ActivityComponentBuilder<MainActivity, MainActivityComponent> {
        Builder module(MainActivityModule module);
    }
}

At this point the code in your activity that builds the component becomes:

    component = ((ActivityComponentBuilderHost) getApplication()).getComponentBuilder(MainActivity.class, MainActivityComponent.Builder.class)
                                                                 .module(new MainActivityModule(this))
                                                                 .build();
    component.inject(this);
jemshit commented 7 years ago

Thanks, what if i add 'Builder module(MainActivityModule module)' into ActivityComponentBuilder itself, any drawbacks you see?

On Dec 22, 2016 18:30, "Trevor Jones" notifications@github.com wrote:

You just add it to the ActivityComponent then add a method to set it on the builder class

@Subcomponent(modules = {MainActivityModule.class})@MainActivityScopepublic interface MainActivityComponent extends PlainComponent {

@Subcomponent.Builder
interface Builder extends ActivityComponentBuilder<MainActivity, MainActivityComponent> {
    Builder module(MainActivityModule module);
}

}

At this point the code in your activity that builds the component becomes:

component = ((ActivityComponentBuilderHost) getApplication()).getComponentBuilder(MainActivity.class, MainActivityComponent.Builder.class)
                                                             .module(new MainActivityModule(this))
                                                             .build();
component.inject(this);

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/trevjonez/Dagger2-MultiBinding-Android-Example/issues/2#issuecomment-268823240, or mute the thread https://github.com/notifications/unsubscribe-auth/AB28nOkTYQ9C1-YPDzZodqZbBCD1Uknzks5rKpecgaJpZM4LUAlO .

trevjonez commented 7 years ago

Biggest draw back is you force that specific module on every component builder that extends the ActivityComponentBuilder interface.

You might consider adding a third generic to ActivityComponentBuilder to force people to define a module for their activity:

public interface ActivityComponentBuilder<ActivityType extends Activity, ComponentType extends PlainComponent<ActivityType>, ModuleType> {
    ActivityComponentBuilder<ActivityType, ComponentType, ModuleType> module(ModuleType module);
    ComponentType build();
}

however you can see that it quickly gets messy. the module method loses the strong type of the builder interface which could be fixed with a fourth generic property which would convert the signature to something like this:

public interface ActivityComponentBuilder<ActivityType extends Activity, ComponentType extends PlainComponent<ActivityType>, ModuleType, Self extends ActivityComponentBuilder<ActivityType, ComponentType, ModuleType, Self>> {
    Self module(ModuleType module);
    ComponentType build();
}

So you can keep the strong typing we had before but it just makes the signature of everything messy and in practice you won't gain much of anything from doing it that way. The only reason we defined these interfaces to begin with is so we can inject a Map of them into the Application.

Plus in my experience(migrating a large app and small app from no DI to dagger2) not every activity component has initially needed a module thus arguably this breaks the interface segregation principal

jemshit commented 7 years ago

ok thanks :+1: