1

I have an unscoped binding inside the appModule and the same class as constructor injected using the Singleton scope. when I add a declaration inside the appComponent for Foo, the generated code picks up the module binding without any DoubleCheck i.e unscoped binding over the constructor injected Singleton binding why is it so?

@Module
public class AppModule {

     @Provides
     public Foo provideFoo() {
         return new Foo();
     }
}

@Component(module = AppModule.class)
@Singleton
public interface AppComponent {
     Foo getFoo();
}

@Singleton
class Foo @Inject constructor(){
     //..
}
Saurabh Kumar
  • 437
  • 1
  • 5
  • 18

1 Answers1

0

There is some hierarchy in how dependencies are provided, I haven't found documentation on this yet, but I ran into the same thing as well. If I recall it correctly from my testing, the hierarchy of where Dagger tries to get the dependency from is the following:

  1. Bound instances (via component builder methods; i.e. @BindsInstance)
  2. Module provision
  3. Constructor injected classes

Somewhere in this list provisioned dependencies should probably also be included (provisioned from a parent component your component has a dependency on), but I dont know where it would be then in the hierarchy.

Usually there is no need to provide the same dependency in multiple ways, why would you both want to provide the dependency via a Module and via constructor injection? If there are multiple dependencies, but they live in a different scope, try using different scopes instead of just the singleton one.

I can think of one reason where you want to use this mechanic, and thats when you normally want a certain dependency to be provided via either constructor or module injection, but specifically for a test build, you want to overwrite that dependency with a different dependency by changing how the component is composed in a test build (i.e. then changing the DaggerComponent so it requires a @BindsInstance method to overwrite the default dependency with a test dependency).

Hylke
  • 598
  • 1
  • 3
  • 17
  • Normally I think this wont be needed normally, correct me if I am wrong here since all the bindings in a single component must match the scope declared for the component so even if we have a single binding in multiple modules for lets say different scopes it would give a compile time error if we tried to include all those modules inside same component since its ambiguous, so why didn't it gave the same error here as well? since I think its pretty much ambiguous since unscoped dependencies can be served from any component and we have a seperately defined binding as well inside the module – Saurabh Kumar Oct 19 '21 at 11:02