Inclusion of several independent components

My dagger configuration for the Android project I'm working on: Note. I provided all the necessary @Component, @Module, @Provides annotations wherever needed.

MainActivity { @Inject A a; @Inject B b; onCreate(){ ComponentX.inject(this); ComponentY.inject(this); } } ComponentX-> ModuleA ->providerA ComponentY -> ModuleB -> providerB 

As you can see, these are two completely independent components that are not connected to each other in any case, except at the injection point.

At compile time, I get the following error:

 In file A.java error: B cannot be provided without an @Provides- or @Produces-annotated method. MainActivity.b [injected field of type: B b] 

Am I mistaken in thinking that when using dagger 2 it is possible to use several components or is it supposed that the application should use one large component that takes care of all injections?

Can someone help me figure out where I am going wrong?

+5
source share
3 answers

You do not need to have one component, there are various ways to modulate them, but each created object or input of values ​​must have all the values ​​provided by one component.

One way to restructure the code is to have a ComponentY component in a ComponentX component, or vice versa, for example.

 @Component(dependencies = ComponentX.class) interface ComponentY { void inject(MainActivity activity); } 

Or you could create a third component, for example ComponentZ, if ComponentX and ComponentY are completely orthogonal to each other.

 @Component(dependencies = {ComponentX.class, ComponentY.class}) interface ComponentZ { void inject(MainActivity activity); } 

Or you can just reuse modules, for example.

 @Component(modules = {ModuleA.class, ModuleB.class}) interface ComponentZ { void inject(MainActivity activity); } 

How exactly you decide to break it up depends a lot on the structure of your code. If components X and Y are visible, but the modules then do not use component dependencies, since they (and modular dependencies) are actually parts of the component implementation. Otherwise, if the modules are visible, simply reuse them again.

I would not use areas for this, since they are really intended for managing objects with different lifetimes, for example. objects associated with a specific user whose service life is the time from which the user logs in when logging out of the system, or the service life of a particular request. If they have different lifespan, you are looking at using areas and subcomponents.

+7
source

is an application that should use one large component

Kind, you should think about it in the field. There is one component for this area. Areas are, for example, ApplicationScope , FragmentScope (saved), ActivityScope , ViewScope . For each area there is a given component; areas are not shared between components.

(This essentially means that if you want to have global singletones in @ApplicationScope , there is one component with an application scope for it. If you need action-specific classes, then you create a component for it for this specific activity, which will depend on component covered by the application).

Refer to @MyDogTom for the annotation of @Subcomponent , but you can also use component dependencies to create sub-components.

 @YScope @Component(dependencies = ComponentX.class, modules=ModuleB.class) public interface ComponentY extends ComponentX { B b(); void inject(MainActivity mainActivity); } @XScope @Component(modules=ModuleA.class) public interface ComponentX{ A a(); } ComponentY componentY = DaggerComponentY.builder().componentX(componentX).build(); 
+2
source

Is it an application that should use one large component that takes care of all injections?

You can use Subcomponent . In your case, the component declaration will look like this:

 @Subcomponent(modules=ModuleB.class) public interface ComponentY{ void inject(MainActivity mainActivity); } @Component(modules=ModuleA.class) public interface ComponentX{ ComponentY plus(ModuleB module); } 

ComponentY creation: creationCompunentY = ComponentX.plus(new ModuleB());

Now in MainActivity you only call ComponentY.inject(this);

 MainActivity { @Inject A a; @Inject B b; onCreate(){ ComponentY.inject(this); } } 

More information about subcomponents can be found in the migration from the Dagger1 manual (see part of the subgraphs), JavaDoc Subcomponent and JavaDoc Component (see part of subcomponents).

0
source

All Articles