How to inject different dependencies for parent/child activities from multiple independent components using Dagger 2?
<p>I'm relatively new to Dagger 2, and I kept running into compiler error from Dagger 2 says missing <code>@Provide</code> or <code>@Produces</code>. What I'm trying to do is inject common components in base class, then child class also has its own component. I checked out several examples online and saw people using sub-component; but I still don't get why can we just have multiple independent components for each class? I don't see why my <code>ImageComponent</code> has to be sub-component of <code>ApiComponent</code>, it just doesn't make any sense. So I'm wondering what's the right approach regarding this issue, or is there any alternative approach that I'm not aware of? Thanks. </p>

<p><code>Api Component</code></p>

<pre><code>public interface UserApi {

    int getUser();
}

public interface SearchApi {

    int search();
}

@Singleton
@Module
public class ApiModule {

    public ApiModule() {
    }

    @Singleton
    @Provides
    public SearchApi provideSearchApi() {
        return new SearchApi() {
            @Override
            public int search() {
                return 0;
            }
        };
    }

    @Singleton
    @Provides
    public UserApi provideUserApi() {
        return new UserApi() {
            @Override
            public int getUser() {
                return 0;
            }
        };
    }
}

@Singleton
@Component(modules = {
    ApiModule.class
})
public interface ApiComponent {

    void inject(BaseActivity activity);
}
</code></pre>

<p><code>Image Component</code>   </p>

<pre><code>public interface ImageLoader {

    boolean load(String url);
}

@ActivityScope
@Module
public class ImageModule {

    @ActivityScope
    @Provides
    public ImageLoader provideImageResource() {
        return new ImageLoader() {
            @Override
            public boolean load(String url) {
                return false;
            }
        };
    }
}

@ActivityScope
@Component(
    modules = {
        ImageModule.class
    }
)
public interface ImageComponent {
    // Dagger doesn't allow this? Not sure why?
    void inject(MainActivity activity);
}
</code></pre>

<p><code>Activity and Components Singleton</code></p>

<pre><code>public class Components {

    private ApiComponent apiComponent;

    private ImageComponent imageComponent;

    private static Components singleton;

    public static void initialize(Context context) {
        if (singleton != null) {
            throw new RuntimeException("Attempted to initialize components twice");
        }
        singleton = new Components(context);
    }

    public static Components get() {
        return singleton;
    }

    private Components(Context context) {
        apiComponent = ApiComponent
            .builder()
            .dataModule(new ApiModule())
            .build();

        // Can't generate image component yet
    }

    public ApiComponent api() {
        return apiComponent;
    }

    public ImageComponent image() {
        return imageComponent;
    }
}
public abstract class BaseActivity extends AppCompatActivity {

    @Inject
    protected UserApi userApi;

    @Inject
    protected SearchApi searchApi;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Components.get().data().inject(this);
    }
}

public class MainActivity extends BaseActivity {

    @Inject
    protected ImageLoader imageLoader;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
</code></pre>

<p><code>stacktrace</code></p>

<pre><code>Error:(15, 10) error: android.com.dagger.data.UserApi cannot be provided without an @Provides- or @Produces-annotated method.
android.com.dagger.BaseActivity.userApi
[injected field of type: android.com.dagger.data.UserApi userApi]
</code></pre>