Dagger2 difference between modules and dependincie

2019-07-10 04:30发布

问题:

I am failing to understand the difference between telling a component what are his modules and telling the component what are its component dependencies.

For example:

@Module public class ModuleA {
    @Provides DependencyA providesDependencyA() {
        return new DependencyA();
    }
}

@Module public class ModuleB {
    @Provides DependencyB providesDependencyB() {
        return new DependencyB();
    }
}

@Component (modules = {ModuleA.class}) 
public interface ComponentA {
    DependencyA getDependencyA();
}

what is the difference between this:

@Component (modules = {ModuleA.class, ModuleB.class}) 
public interface ComponentB {
    DependencyB getDependencyB();
}

And that:

@Component (dependencies = {ComponentA.class}, modules = {ModuleB.class})
public interface ComponentB {
    DependencyB getDependencyB();
}

回答1:

For your simple case, they behave roughly the same; if you'd like, you can think of Dagger's treatment of component dependencies as though it installs an automatically-generated Module that wraps each provision method (zero-arg factory method) on the dependency with a @Provides method that delegates to the instance you pass in. In either case, Dagger will generate a Factory/Provider class implementation that delegates to the module/dependency method you consume.

However, there are some big differences, including these:

  • Modules can take other arbitrary per-method parameters sourced from your object graph. Provision methods in component dependencies have to be zero-arg. This is the most significant difference: Component dependencies are pure external factories, not full participants in your object graph.
  • Module provision methods have to be declared with @Provides for Dagger to consume them, which also allows for non-exposed zero-arg methods. Component dependencies treat every single zero-arg method as a potential provider.
  • Modules have to be annotated with @Module. Component dependencies can be arbitrary types (not necessarily just @Component-annotated instances), and you can pass any implementation whether or not Dagger generates it.
  • Modules and module methods will have their scopes checked; they must be compatible with the enclosing Component's scope. Component dependencies aren't scope-checked.
  • Modules can be abstract classes or interfaces, letting you use @Binds to express declarative bindings within your graph. Component dependencies are instances by definition, and have no access to anything in your object graph.
  • Of course, Modules can declare subcomponents they use or their dependencies on other modules. Component dependencies can do neither; they're just external factories.
  • Instantiable modules don't need to be supplied in a component builder if they have zero-arg public methods. Component dependencies must be provided, even if you were to provide a concrete type Dagger could instantiate.

In short, treat modules as configuration of your graph and component dependencies as externs from outside your graph. Other than the narrow overlap you've described above, it should be pretty clear which role you want for any given class.