对象模块中的 Dagger @Singleton
Dagger @Singleton in object module
我有一个问题,使用不带 @Singleton
函数的 @Module
对象和带 @Singleton
函数的 @Module
class 对象之间是否存在任何显着差异。
很喜欢:
@Module
object ApiModule {
@Provides
fun test()
}
@Module
class ApiModule {
@Singleton
@Provides
fun test()
}
我必须在 object
中标记 @Singleton
吗?
是的,如果没有@Singlton,那么每次您需要注入任何测试时都会调用一次该函数returns。如果你有 @Singleton,return 值将被 dagger 缓存并在每次需要时重复使用。
将 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
。这有关系吗?好吧,创建一个新对象是 slow,并不是很重要,但我们也不需要不必要地降低性能。因此,如果可以的话,您绝对应该更喜欢 object
或 interface
作为模块以获得更好的性能。
至于范围,模块的外观并不重要,重要的是方法签名。 Dagger 查看方法的 return 类型 及其任何注释。所以是的,当然,无论您将什么用于模块,object
、class
或 interface
,您都需要设置范围。 不过,理想情况下,您会在 class 本身上添加范围,并使用构造函数注入来完全避免模块。
tl;dr class
模块会导致创建一个额外的对象,因此 interface
或 object
如果可能,应该首选模块。
我有一个问题,使用不带 @Singleton
函数的 @Module
对象和带 @Singleton
函数的 @Module
class 对象之间是否存在任何显着差异。
很喜欢:
@Module
object ApiModule {
@Provides
fun test()
}
@Module
class ApiModule {
@Singleton
@Provides
fun test()
}
我必须在 object
中标记 @Singleton
吗?
是的,如果没有@Singlton,那么每次您需要注入任何测试时都会调用一次该函数returns。如果你有 @Singleton,return 值将被 dagger 缓存并在每次需要时重复使用。
将 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
。这有关系吗?好吧,创建一个新对象是 slow,并不是很重要,但我们也不需要不必要地降低性能。因此,如果可以的话,您绝对应该更喜欢 object
或 interface
作为模块以获得更好的性能。
至于范围,模块的外观并不重要,重要的是方法签名。 Dagger 查看方法的 return 类型 及其任何注释。所以是的,当然,无论您将什么用于模块,object
、class
或 interface
,您都需要设置范围。 不过,理想情况下,您会在 class 本身上添加范围,并使用构造函数注入来完全避免模块。
tl;dr class
模块会导致创建一个额外的对象,因此 interface
或 object
如果可能,应该首选模块。