2

I have following dagger components structure:

@Singleton @Component(modules = CoreModule.class)
public interface CoreComponent{
    ComponentA plus(ModuleA module);

    ComponentB plus(ModuleB module);
}

@ActivityScope @Subcomponent(modules = ModuleA.class)
public interface ComponentA {
    ComponentA inject(FragmentA fragment);
}

@ActivityScope @Subcomponent(modules = ModuleB.class)
public interface ComponentA {
    ComponentB inject(FragmentB fragment);
}

And client code looks like these:

class FragmentA extends Fragment{
    public FragmentA(){
        App.getCoreComponent().plus(new ModuleA()).inject(this);
    }
}

I've decided to split the application into several gradle modules. I would like to have gradle Core module and 2 modules A and B that depends on the core but doesn't know about each other.

My problem is that CoreComponent uses imports from A and B in order to create subcomponents. So Core is dependent on A and B.

I was trying to solve it using @Components.Builder but that also requires having dagger module in root component with a set of all subcomponents.

Is there any way how to remove the dependency of root component on its subcomponents.

By dependency of the root component I mean that it should know about all subcomponents, that use it.

According to dagger documentation:

Subcomponents are components that inherit and extend the object graph of a parent component. You can use them to partition your application’s object graph into subgraphs either to encapsulate different parts of your application from each other or to use more than one scope within a component.

An object bound in a subcomponent can depend on any object that is bound in its parent component or any ancestor component, in addition to objects that are bound in its own modules. On the other hand, objects bound in parent components can’t depend on those bound in subcomponents; nor can objects bound in one subcomponent depend on objects bound in sibling subcomponents.

Rostyslav Roshak
  • 3,859
  • 2
  • 35
  • 56

1 Answers1

2

You won't be able to remove dependency CoreComponent -> ComponentA, ComponentB using subcomponents. This is just not the way subcomponents work.

You could try to reverse this dependency by making ComponentA and ComponentB depend upon CoreComponent (ComponentA, ComponentB -> CoreComponent). This will require that you explicitly export objects in CoreComponent.

As a side note I must warn you that what you're trying to do will probably cause a big headache in the future: coupling internal implementations of modules through third party framework is rarely a good idea.

Vasiliy
  • 16,221
  • 11
  • 71
  • 127
  • I thought about changing my subcomponents to components, but I don't want to explicitly show all of the dependencies, since the real app is huge and there would be much more dependencies. – Rostyslav Roshak Apr 04 '17 at 12:37
  • 2
    @RostyslavRoshak I can't give you any specific advice, but in general I would try to remove `Dagger` related code from all modules except the "top" one. I would also try to partition my logic in such a way that dependencies between "gradle modules" are uni-directional (i.e. if `Core` module depends on `A`, `A` will not be dependent on `Core`) – Vasiliy Apr 04 '17 at 12:41