-->

Can I use some kind of assisted Inject with Dagger

2019-01-20 15:36发布

问题:

With Google Guice or Gin I can specify parameter with are not controlled by the dependency injection framework:

class SomeEditor {


  @Inject
  public SomeEditor(SomeClassA a, @Assisted("stage") SomeClassB b) {
  }

}

The assisted parameter stage is specified at the time an instance of SomeEditor is created.

The instance of SomeClassA is taken from the object graph and the instance of SomeClassB is taken from the caller at runtime.

Is there a similar way of doing this in Dagger?

回答1:

Because factories are a separate type of boilerplate to optimize away (see mailing list discussion here), Dagger leaves it to a sister project, AutoFactory. This provides the "assisted injection" functionality Guice offers via FactoryModuleBuilder, but with some extra benefits:

  • You can keep using AutoFactory with Guice or Dagger or any other JSR-330 dependency injection framework, so you can keep using AutoFactory even if you switch between them.
  • Because AutoFactory generates code, you don't need to write an interface to represent the constructor: AutoFactory will write a brand new type for you to compile against. (You can also specify an interface to implement, if you'd prefer, or if you're migrating from Guice.)
  • Because all the type inspection happens at compile-time, it produces plain old Java, which doesn't have any slowness due to reflection and which works well with debuggers and optimizers. This makes the Auto library particularly useful for Android development.

Example, pulled from AutoFactory's README, which will produce a SomeClassFactory with providedDepA in an @Inject-annotated constructor and depB in a create method:

@AutoFactory
final class SomeClass {
  private final String providedDepA;
  private final String depB;

  SomeClass(@Provided @AQualifier String providedDepA, String depB) {
    this.providedDepA = providedDepA;
    this.depB = depB;
  }

  // …
}


回答2:

Yes, please check this Square project: square/AssistedInject

Currently it is not in 1.0 yet for purpose. They wait until Dagger will introduce a public API for registering those generated Module classes automatically - see this issue. With that you won't have to reference them in your Dagger code as in this example from README:

@AssistedModule
@Module(includes = AssistedInject_PresenterModule.class)
abstract class PresenterModule {}