Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple independent component injection

My dagger configuration for an android project that i'm working on: Note: I've provided all the needed @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 not related to each other in anyway except for at the point of injection.

During compilation 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 multiple components can be used while using dagger 2 or is the application supposed to use one big component which takes care of all the injections?

Can anyone help me understand where i'm going wrong?

like image 672
gaara87 Avatar asked Sep 01 '15 22:09

gaara87


1 Answers

You do not have to have a single component, there are various ways to modularize them, but each object that you create, or inject values into, must have all its values provided by a single component.

One way you could restructure your code is to have ComponentY depend on ComponentX, or vice versa, e.g.

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

Or you could create a third Component, say ComponentZ, if ComponentX and ComponentY are completely orthogonal to one another.

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

Or you could just reuse the modules, e.g.

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

How exactly you decide to split it largely depends on the structure of your code. If the components X and Y are visible but the modules are not then use component dependencies, as they (and module depedencies) are really implementation details of the component. Otherwise, if the modules are visible then simple reuse them.

I wouldn't use scopes for this as they are really for managing objects with different lifespans, e.g. objects associated with a specific user whose lifespan is the time from when a user logs in to when they log out, or the lifespan of a specific request. If they do have different lifespan then you are looking at using scopes and subcomponents.

like image 150
Paul Duffin Avatar answered Sep 18 '22 01:09

Paul Duffin