11

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.

Matthias
  • 4,481
  • 12
  • 45
  • 84
Héctor
  • 24,444
  • 35
  • 132
  • 243

2 Answers2

10

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.

David Medenjak
  • 33,993
  • 14
  • 106
  • 134
0

It's getting mad because you're saying you can inject into that class but you're not providing a class that it's expecting you to provide. You just need to add the OauthModule to your LoggedUserComponent. Try this

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

    void inject(LoginActivity loginActivity);

}
ootinii
  • 1,795
  • 20
  • 15