Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger2: Error when two components has same inject method signature

I have this component:

@Singleton
@Component(modules = OauthModule.class)
public interface OauthComponent {

    void inject(LoginActivity a);

}

and the module:

@Module
public class OauthModule {

    @Provides
    @Singleton
    Oauth2Service provideOauth2Service() {
        return new Oauth2StaticService();
    }

}

and this another component:

@Singleton
@Component(modules = LoggedUserModule.class)
public interface LoggedUserComponent {

    void inject(LoginActivity a);

}

and I get this error:

Error:(15, 10) error: Oauth2Service cannot be provided without an @Provides- or @Produces-annotated method.

If I change the LoggedUserComponent's inject method parameter to be another Activity, say AnotherActivity like this:

@Singleton
@Component(modules = LoggedUserModule.class)
public interface LoggedUserComponent {

    void inject(AnotherActivity a);

}

compilation is ok. Why? Can't I have two components with the same inject signature?

I'm trying to understand how Dagger works so any help will be appreciated. Thanks.

like image 420
Héctor Avatar asked Mar 03 '16 18:03

Héctor


1 Answers

Think of dagger as an object graph—which it actually is. You probably should not have 2 different components being able to inject the same object, other than for testing purposes (or if you want to include different behavior, not additional one).

If your LoginActivity depends on multiple modules, you should aggregate them in a single component, since as your error shows, dagger will fail if it can not provide all dependencies from a single component.

@Singleton
@Component(modules = {LoggedUserModule.class, OauthModule.class})
public interface LoggedUserComponent {

    void inject(AnotherActivity a);

}

Looking at Oauth2Service, this could easily be something that multiple objects could use, so a higher scope could be adequate. In that case you should think about adding it with a @Singleton scope to your application component, or maybe create its own component with e.g. a @UserScope.

Then you would have to either make your LoggedUserComponent a @Subcomponent or declare this component a dependency using @Component(dependencies = OauthComponent.class) and providing a getter in OauthComponent for it. In both cases dagger would also be able to provide the dependency found higher in the graph, thus also resolving your error.

like image 165
David Medenjak Avatar answered Sep 21 '22 16:09

David Medenjak