Search code examples
dagger-2dagger

How to use AndroidInjector.Factory?


I'm migrating from Dagger 2.21 and Builder is changed to Factory. How is AndroidInjector.Factory supposed to be used? I have this component

interface AppComponent : AndroidInjector<MainApplication> {

    @Component.Factory
    interface Factory : AndroidInjector.Factory<MainApplication> {

        fun create(@BindsInstance emailId: String) : AppComponent
    }
}

But it fails with "error: @Component.Factory types must have exactly one abstract method. Already found: create(T)".

AndroidInjector.Factory already seems to have a create which binds MainApplication instance. How am i supposed to bind another value? The only workaround i found is not to extend from AndroidInjector.Factory like this but then why have AndroidInjectory.Factory?

interface AppComponent : AndroidInjector<MainApplication> {

    @Component.Factory
    interface Factory {

        fun create(@BindsInstance instance: MainApplication,
                   @BindsInstance emailId: String) : AppComponent
    }
}

Solution

  • You don't need (and as you noticed you actually can't) to extend AndroidInjector.Factory when you have additional parameters needed to create the component.

    You should extend AndroidInjector.Factory when you are using dagger-android to inject dependencies into android components using AndroidInjection.inject(). To make this injection possible you need to follow some rules, in particular your component's factory should extend AndroidInjector.Factory.

    AndroidInjector.Factory defines AndroidInjector<T> create(@BindsInstance T instance), which will be used by dagger-android to instantiate this subcomponent, so you can't add any additional parameters.

    Update:

    Dagger and dagger-android are two different libraries. Dagger is a general DI framework, it does not contain any android-specific code. Component.Factory comes from dagger itself and you are free to add a method with any number of parameters, which will be used to create your subcomponent.

    Dagger-android in its turn is an android-specific library which greatly reduces boilerplate code that you need to write by generating it. But you loose some flexibility and have to follow the structure defined by the library. Here your factory method cannot have any additional parameters and the factory should extend AndroidInjector.Factory.

    Generally you can also mix both approaches in one project, but I would not recommend to do so to make your code consistent.