Поскольку Dagger является процессором аннотаций, часто самое простое и простое решение - просто взглянуть на сгенерированный код.
Я подготовил минимальный образец для демонстрации:
class Foo()
class Bar()
@Component(modules = [ClassModule::class, ObjectModule::class])
interface FooComponent {
val foo: Foo
val bar: Bar
}
@Module
class ClassModule {
@Provides
fun foo() = Foo()
}
@Module
object ObjectModule {
@Provides
fun bar() = Bar()
}
Если мы посмотрим на сгенерированный код, то увидим следующее (я удалил некоторые ненужные биты, просто скомпилируйте приведенный выше код и посмотрите на реализацию, если хотите увидеть все это)
public final class DaggerFooComponent implements FooComponent {
private final ClassModule classModule;
private DaggerFooComponent(ClassModule classModuleParam) {
this.classModule = classModuleParam;
}
public static Builder builder() {
return new Builder();
}
@Override
public Foo getFoo() {
return ClassModule_FooFactory.foo(classModule);}
@Override
public Bar getBar() {
return ObjectModule_BarFactory.bar();}
public static final class Builder {
private ClassModule classModule;
private Builder() {
}
public Builder classModule(ClassModule classModule) {
this.classModule = Preconditions.checkNotNull(classModule);
return this;
}
public FooComponent build() {
if (classModule == null) {
this.classModule = new ClassModule();
}
return new DaggerFooComponent(classModule);
}
}
}
Что вы заметите, так это то, что Dagger создает объект для ClassModule
, но напрямую использует ObjectModule
с его методом stati c. Имеет ли это значение? Что ж, создание нового объекта медленно , не так много, что это действительно имеет значение, но нам также не нужно без необходимости снижать производительность. Поэтому, если вы можете, вам определенно предпочтительнее использовать object
или interface
в качестве модулей для повышения производительности.
Что касается области действия, то на самом деле не имеет значения, как выглядят ваши модули, это сигнатура метода, которая на счет. Кинжал просматривает возвращаемый тип метода вместе с любой аннотацией к нему. Так что да, конечно, вам нужно установить область независимо от того, что вы используете для вашего модуля, object
, class
или interface
. В идеале вы бы добавили область видимости к самому классу и использовали бы инжектор конструктора, чтобы вообще избежать модулей.
tl; dr class
Модули приводят к созданию дополнительного объекта, поэтому предпочтение отдается модулям interface
или object
, если это возможно.