0

I am searching for a way or design pattern i can use so that dagger2 components to not have so many inject calls. Lets have a look at what i mean on a enterprise level:

Singleton
          @Component(modules = {AppModule.class, NetworkModule.class, RepositoryModule.class})
          public interface AppComponent {

              void inject(UserDataRepository target);

              void inject(DoStandardLoginUsecase target);

              void inject(NetworkSessionManager target);

              void inject(SharedPrefRepo target);

              void inject(getSharedPrefUsecase target);

              ActivitySubComponent plus(ActivityModule activityModule);

              PresenterSubComponent plus(PresenterModule presenterModule, UseCaseModule useCaseModule);
}
//.. this list is going to be gigantic in a year. how can i minimize it or make the inject calls somewhere else or group them ?

I need a way to group the inject calls somewhere else before they get out of control.

j2emanue
  • 60,549
  • 65
  • 286
  • 456
  • 1
    Are `UserDataRepository`, `NetworkSessionManager`, etc extending Android Framework components? Why don't you let them be constructor injected? – David Medenjak Jun 09 '17 at 15:11
  • Because i find it so hard to know what's being provided if i do that. You mean dont put the dependency in a module but rather just mark the constructor right? – j2emanue Jun 09 '17 at 15:51
  • 1
    Yes. If you use constructor injection you can get rid of all those `inject(...)` lines – David Medenjak Jun 09 '17 at 16:02
  • hey thanks for the response. but if you take a look at the accepted answer of this post: https://stackoverflow.com/questions/32076244/dagger-2-injecting-parameters-of-constructor the author is putting the method names inside the component interface ? specifically: Singleton @Component // no modules public interface SingletonComponent { Thermosiphon thermosiphon(); Heater heater(); void inject(Something something); } he is doing this even though he is doing constructor injection ... i must be missing something ? – j2emanue Jun 09 '17 at 21:42
  • `Heater getHeater()` exposes a getter to manually get the object or expose it to dependent components, `void inject(Something something)` injects your objects, which you should do for framework components (only default constructors) but can avoid for your own code (use constructor injection instead). Your code seems to inject everything manually, and as pointed out, you could just switch to constructor injection – David Medenjak Jun 09 '17 at 22:07

1 Answers1

1

Remember that your Component is a list of entry points into your object graph, and that your objects can depend on each other without being listed on the Component. This is true regardless of whether you use constructor injection or module configuration. Consequently, your Component will likely only include an inject for your classes that Dagger can't or shouldn't instantiate itself, including your Application, Activities, Fragments, and other system services.

It's also true that Dagger will populate @Inject fields and call @Inject methods itself after calling the constructor:

public class UserDataRepository {
  @Inject public UserDataRepository() {}  /** So Dagger knows how to create one */

  @Inject FieldOne fieldOne;
  @Inject FieldTwo fieldTwo;

  @Inject void initialize(DepThree depThree, DepFour depFour) {
    // ...
  }

  // ...
}

Though I personally prefer constructor injection so I can set those fields to final, you may prefer keeping them mutable and @Inject-annotated; that doesn't mean you need to list them on your Component or construct them using a Module.

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251